简体   繁体   English

memcpy()似乎不起作用

[英]memcpy() doesn't seem to work

I'm having trouble with memcpy() and I don't have a clue on where I went wrong. 我在使用memcpy()时遇到了麻烦,但是我不知道哪里出了问题。

Code can be seen here: http://pastebin.com/tebksExR 可以在这里查看代码: 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;
}

On executing it, all I see is just "STR". 执行它时,我看到的只是“ STR”。 Nothing is seen on the memory region pointed by str too. 在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 ""

Where did I go wrong? 我哪里做错了?

Thanks! 谢谢!

When you specify %s , printf expects a null-terminated string. 当您指定%sprintf需要以空值结尾的字符串。 It can't tell that you allocated 18 bytes and you want the contents of those bytes printed. 它不能告诉您分配了18个字节,并且想要打印这些字节的内容。 It looks at *str , sees a null byte, and stops looking. 它查看*str ,看到一个空字节,然后停止查找。

Your data is getting moved. 您的数据得到感动。 If you declared: 如果您声明:

tmp_str* str2 = (tmp_str*)str;

then it would display properly in the debugger. 那么它将在调试器中正确显示。 You're just looking at the data wrong-- your code is executing properly. 您只是在看数据错误-您的代码正确执行。

As was pointed out, since the first byte of str is '\\0' . 如前所述,由于str的第一个字节是'\\0' a simple printf("%s",str); 一个简单的printf("%s",str); statement will do nothing (it will stop at the first byte which indicates "end of string"). 语句将不执行任何操作(它将在指示“字符串结尾”的第一个字节处停止)。 Instead, you could try 相反,您可以尝试

int ii;
printf("STR in hex:\n");
for(ii = 0; ii < sizeof(hdr); ii++) {
  printf("%02x ", str[ii]);
}
printf("\n");

This will now print every byte in str as a hex number; 现在,这会将str中的每个字节打印为十六进制数字。 you will see that the copy went OK. 您会看到复制正常。

If you would like, you could replace this with 如果您愿意,可以将其替换为

int ii;
printf("STR in hex:\n");
for(ii = 0; ii < sizeof(hdr); ii++) {
  printf("%c", str[ii]);
}
printf("\n");

And you will see the actual characters (but some of them may be "unprintable" and might have unexpected side effects in your terminal). 您将看到实际的字符(但是其中某些字符可能是“无法打印的”,并且可能会在终端中产生意外的副作用)。

str is a string ( char * terminated by '\\0' ) and hdr is a structure, which doesn't even have a string field. str是一个字符串( char *'\\0'结尾), hdr是一个结构,甚至没有字符串字段。 If you want to convert hdr to a human-readable string, you'll have to use printf or sprintf with the proper conversion specifiers. 如果要将hdr转换为人类可读的字符串,则必须使用带有适当转换说明符的printfsprintf

Well, you set hdr.num = 0; 好吧,您将hdr.num = 0;设置hdr.num = 0; , so the first byte of copied chunk of memory is equal to 0 , so the first character of your string is NULL, which marks it's ending, so nothing is printed. ,因此复制的内存块的第一个字节等于0 ,因此字符串的第一个字符为NULL,这表明它的结尾,因此不打印任何内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM