char *a=NULL;
char *s=NULL;
a=(char *)calloc(1,(sizeof(char)));
s=(char *)calloc(1,(sizeof(char)));
a="DATA";
memcpy(s,a,(strlen(a)));
printf("%s",s);
请问为什么它会打印出DATA½½½½½½½½■ε■?如何只打印出DATA?谢谢。
char *a=NULL;
char *s=NULL;
a=(char *)calloc(1,(sizeof(char)));
s=(char *)calloc(1,(sizeof(char)));
a="DATA";
memcpy(s,a,(strlen(a)));
printf("%s",s);
请问为什么它会打印出DATA½½½½½½½½■ε■?如何只打印出DATA?谢谢。
C语言中的字符串以零字符值(nul)结尾。
strlen返回零之前的字符数。
所以你不会复制零。
printf会继续运行,打印s后面的内存中的任何内容,直到遇到零。
你只创建了一个大小为1的缓冲区,所以你在写入数据时会覆盖s后面的任何内容,并且在将a设置为文字之前泄漏了calloc给a分配的内存。
在找到字符串的长度后为s分配内存,再分配一个字节来包括nul终止符,然后将a复制到s中。你不需要为a分配任何内存,因为C运行时负责存储文字“DATA”。
puts("DATA");
你需要更清楚地表达你想做什么,才能得到关于指针/分配/复制的帮助。
Your
a="DATA";
将指向分配内存的指针清除。它不会将“DATA”复制到内存中。然而,这样做是不够的,因为
a=(char *)calloc(1,(sizeof(char)));
分配一块单独的字符内存。但是
memcpy(s,a,(strlen(a)));
memcpy
函数将指向字符串常量“DATA”的地址所指向的内容复制到指向s的内存中。但需要注意的是,s
指向的是一段已分配的单个字符,如果复制超过一个字符,可能会覆盖其他位置的数据导致错误。
strlen(a)
返回4(即“DATA”的长度),memcpy
将刚好复制4个字符。但为了知道字符串在哪里结束,C语言约定在字符串末尾加上一个空字符('\0')。因此,“DATA”在内存中实际上是由'D''A''T''A''\0'组成的。
所有与字符串有关的函数都期望以空字符结尾,并在遇到空字符前一直输出字符串内容。
要复制字符串,请使用strcpy
(或strncpy
)函数,它会连同空字符一起复制。但需要注意的是,strcpy
存在“安全”漏洞,因为可以溢出目标缓冲区。
然而,我看到的最大问题是你只为和s各预留了一个字符的内存空间,这样“DATA\0”是无处放置的。
strlen函数只计算字符串中的字符数量,不包括终止符'\0'。 没有这个终止符,printf函数就无法知道字符串的结尾。
解决方法: memcpy(s,a,(strlen(a)+1));
你需要在 DATA
字符串后面存储一个终止符 \0
,这样 printf()
才会知道何时停止打印。
你可以用 strcat
替换 memcpy
:
strcat(s, a);
应该这样做。
然而,请注意,之前有一个错误:
calloc(1,sizeof(char))
只会分配一个字节!这显然不够!根据实现,您的程序可能会崩溃或不会崩溃。
您为1个字符保留了空间,因此当您在写入“DATA”时(它包括4个字符和一个用于标记字符串结尾的结尾符 \0
),实际上使用了其他某个变量的内存。
a=(char *)calloc(1,(sizeof(char)));
对于这个例子,您需要5个或更多字符:
a=(char *)calloc(5, (sizeof(char)));