2013-11-28 231 views
0

我遇到了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 "" 

我哪裏錯了?

謝謝!

回答

2

當您指定%s時,printf需要以null結尾的字符串。它不能分辨出你分配了18個字節,而你想要打印這些字節的內容。它看起來在*str,看到一個空字節,並停止尋找。

+0

是的,這是正確的,但爲什麼由str指出的內存區域爲空(在gdb跟蹤中)? – hdnivara

+0

@ F430:因爲GDB也期待一個以null結尾的字符串。 – user2357112

+0

@ ^:那我怎麼能看到內存裏有什麼?我想我不能使用str,因爲它是一個char * – hdnivara

1

str是一個字符串(char *終止於'\0')和hdr是一個結構,它甚至沒有字符串字段。如果要將hdr轉換爲可讀的字符串,則必須使用printfsprintf以及適當的轉換說明符。

+0

我只是想要數據移動,實際上並沒有試圖使hdr成爲一個字符串。 – hdnivara

+0

在這種情況下,您應該將其複製到另一個'tmp_str'中... –

1

那麼,你設置了hdr.num = 0;,所以複製的內存塊的第一個字節等於0,所以你的字符串的第一個字符是NULL,這表示它的結束,所以什麼都不打印。

2

您的數據正在移動。如果你聲明:

tmp_str* str2 = (tmp_str*)str; 

那麼它會在調試器中正確顯示。你只是看錯了數據 - 你的代碼正在正確執行。

2

正如所指出的,由於str的第一個字節是'\0'。一個簡單的printf("%s",str);語句將不會執行任何操作(它將停止在指示「字符串結束」的第一個字節處)。相反,你可以嘗試

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"); 

代替這一點,你就會看到實際的字符(但其中一些可能是「不可打印的」,並有可能在終端意想不到的副作用)。