2013-11-28 3 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 ожидает строку с нулевым символом. Он не может сказать, что вы выделили 18 байтов, и вы хотите, чтобы содержимое этих байтов было напечатано. Он смотрит на *str, видит нулевой байт и перестает смотреть.

+0

Да, это правильно, но почему область памяти, на которую указывает str, пуста (в трассировке gdb)? – hdnivara

+0

@ F430: Поскольку GDB также ожидает строку с нулевым завершением. – user2357112

+0

@ ^: Тогда, как я могу увидеть, что там в памяти? Я думаю, я не могу использовать str, поскольку это char * – hdnivara

1

str является строкой (char * завершается '\0') и hdr представляет собой структуру, которая даже не имеет поля строки. Если вы хотите конвертировать hdr в удобочитаемую строку, вам нужно будет использовать printf или sprintf с соответствующими спецификаторами преобразования.

+0

Мне просто нужно движение данных и на самом деле не пытаюсь сделать hdr, строку. – hdnivara

+0

В этом случае вы должны скопировать его в другой 'tmp_str' ... –

1

Ну, вы установили hdr.num = 0;, поэтому первый байт скопированного фрагмента памяти равен 0, поэтому первый символ вашей строки равен NULL, что означает, что он заканчивается, поэтому ничего не печатается.

2

Ваши данные is перемещение. Если вы заявили:

tmp_str* str2 = (tmp_str*)str; 

тогда он правильно отобразился в отладчике. Вы просто смотрите на данные неправильно - ваш код работает правильно.

2

Как указывалось, поскольку первый байт str is '\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"); 

И вы увидите реальные символы (но некоторые из них могут быть «непечатные» и может иметь неожиданные побочные эффекты в вашем терминале).

Смежные вопросы