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½½½½½½½■■???????????????????谢谢
答案 0 :(得分:6)
C中的字符串以零字符值(nul)终止。
strlen返回零之前的字符数。
所以你没有复制零。
printf继续前进,在s之后打印内存中的任何内容,直到它达到零。
您也只是创建一个大小为1的缓冲区,因此您在s之后的任何内容上写入数据,并且在将set设置为文字之前将内存calloc泄漏到a。
在找到字符串的长度后为s分配内存,再分配一个字节以包含nul终止符,然后将a复制到s中。在存储文字“DATA”后,您不需要为C运行时分配任何内容。
答案 1 :(得分:2)
您首先分配内存,然后通过使用字符串文字重新分配指针来抛弃该内存。您对calloc()
的论证也看起来非常错误。
此外,memcpy()
不是字符串复制功能,它不包括终结符。您应该使用strcpy()
。
仅打印DATA的最佳方法似乎是
puts("DATA");
您需要更清楚自己想做什么,以获得有关指针/分配/复制的帮助。
答案 2 :(得分:2)
strlen只计算没有终结符'\ 0'的字符。 如果没有这个终结符,printf就不会知道字符串的结尾。
解决方案: 的memcpy(S,A,(strlen的(A)1));
答案 3 :(得分:1)
您正在为1个字符保留空间,因此当您编写“DATA”(4个字符+尾随\0
以标记字符串的结尾)时,您实际上正在使用其他变量的内存。
a=(char *)calloc(1,(sizeof(char)));
对于此示例,您需要5个或更多字符:
a=(char *)calloc(5, (sizeof(char)));
答案 4 :(得分:1)
您需要在\0
字符串之后存储终止DATA
,以便printf()
知道停止打印。
您可以将memcpy
替换为strcat
:
strcat(s, a);
应该这样做。
但请注意,之前存在一个错误:
calloc(1,sizeof(char))
只会分配一个字节!这当然不够!根据实施情况,您的计划可能会崩溃,也可能不会崩溃。
答案 5 :(得分:1)
您
a="DATA";
将指针转换为已分配的内存。它不会将“DATA”复制到内存中。然而,这还不足以存储它,因为
a=(char *)calloc(1,(sizeof(char)));
分配一个char。而
memcpy(s,a,(strlen(a)));
将(字符串文字“DATA”)现在指向的内容复制到s指向的内存中。但同样,s
指向分配的单个字符,并且复制超过1个字符将覆盖某些内容并导致错误。
strlen(a)
给你4(“DATA”的长度)和memcpy复制4个char。但要知道字符串的结束位置,C使用约定将最终的“null”字符('\ 0')放到其末尾。所以“数据”确实在记忆中是'D''''T''''\ 0'。
所有与字符串相关的函数都需要空字节,并且在找到之前它们不会停止打印。
要复制字符串,请使用strcpy
(或strncpy
),它也会复制字符串及其最终的空字节。 (strcpy
不太“安全”,因为你可以溢出目标缓冲区。)
但我在这里看到的最大问题是你只保留了一个字符(而你将其丢弃)和s,所以DATA \ 0将不适合任何地方。