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
,这会触发未定义的行为strcpy
将过长的字符串复制到p
,包括一个零终止符(参见c文档)
因此,q
将指向p
+32字节,解释剩余的行为
旁注:如果你接近C,尤其是作为一个初学者,一定要准备好文档。未定义的行为经常发生
malloc()
的任何两个调用的返回值之间不需要任何特定的关系,即使是像您这样的连续调用
在实践中,C实现倾向于以多字节粒度分配内存,即使请求的大小较小,这也是您所观察到的。这绝对不意味着可以访问超出显式请求边界的内存
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复制空值。