Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 字符指针空终止和内存分配_C_String_Char_Null Terminated - Fatal编程技术网

C 字符指针空终止和内存分配

C 字符指针空终止和内存分配,c,string,char,null-terminated,C,String,Char,Null Terminated,我有以下程序:我的程序编译得很好,并给出如下所述的输出。我对下面列出的输出有一些疑问。 *******************************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char *p = malloc(sizeof(char))

我有以下程序:我的程序编译得很好,并给出如下所述的输出。我对下面列出的输出有一些疑问。 *******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
    char *p = malloc(sizeof(char));
    char *q = malloc(sizeof(char));
    printf("address of p = %p \n", p); A
    printf("address of q = %p \n", q); B
    strcpy(p, "abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz");
    printf("Value in P : %s \n", p); C
    printf("Value in q : %s\n", q); D
    printf("string length of P : %d \n", strlen(p)); E
    printf("string lenght of q : %d\n", strlen(q)); F

    return 0;
}

===OUTPUT ==
address of p = 0xbbf010 
address of q = 0xbbf030 
Value in P : abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvwxyz 
Value in q : 789abcdefghijklmnopqrstuvwxyz
string length of P : 61 
string lenght of q : 29
#包括
#包括
#包括
int main()
{
char*p=malloc(sizeof(char));
char*q=malloc(sizeof(char));
printf(“p的地址=%p\n”,p);A
printf(“q的地址=%p\n”,q);B

strcpy(p,“abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvxyz”); printf(“P中的值:%s\n”,P);C printf(“q中的值:%s\n”,q);D printf(“P的字符串长度:%d\n”,strlen(P));E printf(“q的字符串长度:%d\n”,strlen(q));F 返回0; } ==输出== p=0xbbf010的地址 q=0xbbf030的地址
P中的值:abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvxyz q:789abcdefghijklmnopqrstuvwxyz中的值 P的字符串长度:61 q:29的字符串长度
=======输出端==

问题:
1.为什么p和q的地址之间有32个字节的差异。我只为P分配了1个字节。连续的
malloc
之间的32字节差异是如何自动产生的?
2.我没有
NULL
终止我的字符串。如何
printf
检测
\0
终止?
3.
strlen
在没有
\0
终止的情况下如何正常工作

  • p
    q
    分配1字节的存储空间
  • 您将一个比这个长得多的字符串(事实上,任何比空字符串长的字符串都不适合)复制到
    p
    ,这会触发未定义的行为
  • 由于编译器下面的C std库(实际上是它的malloc实现)似乎选择了32字节对齐的分配,而且中间没有其他分配发生,因此在您的例子中,这两个指针相隔32字节

    strcpy
    将过长的字符串复制到
    p
    ,包括一个零终止符(参见c文档)

    因此,
    q
    将指向
    p
    +32字节,解释剩余的行为

    旁注:如果你接近C,尤其是作为一个初学者,一定要准备好文档。未定义的行为经常发生

  • 为什么p和q的地址之间有32个字节的差异。我只为P分配了1个字节。如何自动分配32个字节的差异 在连续的malloc之间
  • 因为这是您的实现选择的方式。对
    malloc()
    的任何两个调用的返回值之间不需要任何特定的关系,即使是像您这样的连续调用

    在实践中,C实现倾向于以多字节粒度分配内存,即使请求的大小较小,这也是您所观察到的。这绝对不意味着可以访问超出显式请求边界的内存

  • 我没有空终止我的字符串。printf如何检测\0终止
  • strlen如何在没有\0终止的情况下正常工作
  • 谁说你的字符串没有终止?字符串文本当然是。除此之外,您还通过超出
    p
    指向的分配空间的边界来产生未定义的行为,因此任何事情都可能发生

    如果您想推测UB,那么您可能会根据观察到的输出猜测,
    strcpy
    *p
    开始将源字符串中的字节复制到内存中,继续执行该字符串与
    *q
    之间的所有未分配字节,然后进入
    *q
    之外的未分配空间,直到它最终复制nul字节。然后,您可能会猜测
    printf
    strlen
    类似地从一个或另一个起点读取未分配的区域


    这可能会也可能不会准确地描述实际发生的情况,在任何情况下,您都不应将观察到的结果解释为表明此类程序行为是可预测或可接受的。特别是,此类行为通常会损坏分配器的元数据,当您尝试释放分配的空间或分配其他空间时,可能会出现这种情况。

    strcpy(p,“abcdefghijklmnopqrstuvwxyz123456789abcdefghijklmnopqrstuvxyz”)调用未定义的行为-从该代码中获得的任何结果都是无意义的
    char*p=malloc(sizeof(char))=您分配1个字节,然后将更长的字符串复制到此地址,因此您正在覆盖随机内存位置(@UnholySheep),并且地址之间的差异超过1个字节,因为内存通常分配在对齐的地址上。它的对齐方式因编译器和系统而异,但通常在4、8、16或32字节边界上对齐。零终止是由strcpy引起的。查找:-)@无限字符可以从任何字节地址开始,但malloc总是分配对齐的存储。它选择的对齐方式未定义。“ABCDEFGHIJKLMNOPQRSTUVXYZ123456789ABDEFGHIJKLMNOPQRSTUVXYZ”具有空值,strcpy复制空值。