memcpy()似乎不起作用

时间:2013-11-28 21:46:15

标签: c memcpy

我在使用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 ""

我哪里出错了?

谢谢!

5 个答案:

答案 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转换为人类可读的字符串,则必须使用printfsprintf和正确的转换说明符。

答案 4 :(得分:1)

好吧,你设置hdr.num = 0;,所以复制的内存块的第一个字节等于0,所以你的字符串的第一个字符是NULL,这标志着它的结束,所以没有打印。