我在使用memcpy()时遇到问题,而且我不知道哪里出错了。
代码可以在这里看到:http://pastebin.com/tebksExR
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct tmp__ {
unsigned int num;
unsigned short id;
unsigned short type;
} tmp_str;
int
main(int argc, char **argv)
{
tmp_str hdr;
char *str = NULL;
str = calloc(18, sizeof(char));
memset(&hdr, 0, sizeof(hdr));
hdr.num = 0;
hdr.id = 0;
hdr.type = 21845;
memcpy((void *) str, (void *) &hdr, sizeof(hdr));
printf("STR: %s\n", str);
free(str);
return 0;
}
在执行它时,我看到的只是“STR”。在str指向的内存区域也没有看到任何东西。
(gdb) b 23
Breakpoint 1 at 0x8048494: file memcpy.c, line 23.
(gdb) run
Starting program: /home/a.out
Breakpoint 1, main (argc=1, argv=0xbffff234) at memcpy.c:23
23 memcpy((void *) str, (void *) &hdr, sizeof(hdr));
(gdb) n
24 printf("STR: %s\n", str);
(gdb) n
STR:
26 free(str);
(gdb) info locals
hdr = {num = 0, id = 0, type = 21845}
str = 0x804b008 ""
我哪里出错了?
谢谢!
答案 0 :(得分:2)
指定%s
时,printf
需要以空字符结尾的字符串。它不能告诉您分配了18个字节,并且您希望打印这些字节的内容。它查看*str
,看到一个空字节,然后停止查找。
答案 1 :(得分:2)
您的数据 被移动。如果您声明:
tmp_str* str2 = (tmp_str*)str;
然后它会在调试器中正确显示。您只是看错了数据 - 您的代码正在正确执行。
答案 2 :(得分:2)
正如所指出的,因为str
的第一个字节是'\0'
。一个简单的printf("%s",str);
语句将不执行任何操作(它将在第一个字节处停止,表示&#34;字符串结束&#34;)。相反,你可以尝试
int ii;
printf("STR in hex:\n");
for(ii = 0; ii < sizeof(hdr); ii++) {
printf("%02x ", str[ii]);
}
printf("\n");
现在将打印str
中的每个字节作为十六进制数字;你会看到副本没问题。
如果您愿意,可以用
替换它int ii;
printf("STR in hex:\n");
for(ii = 0; ii < sizeof(hdr); ii++) {
printf("%c", str[ii]);
}
printf("\n");
你会看到实际的角色(但其中一些可能是&#34;不可打印&#34;并且可能在您的终端中产生意外的副作用)。
答案 3 :(得分:1)
str
是一个字符串(char *
以'\0'
结尾),hdr
是一个结构,甚至没有字符串字段。如果您想将hdr
转换为人类可读的字符串,则必须使用printf
或sprintf
和正确的转换说明符。
答案 4 :(得分:1)
好吧,你设置hdr.num = 0;
,所以复制的内存块的第一个字节等于0
,所以你的字符串的第一个字符是NULL,这标志着它的结束,所以没有打印。