C Valgrind - Перекрытие источника и назначения в memcpy

Я новичок в программировании на C и пишу простое клиент-серверное приложение. Я получаю это сообщение:

 Source and destination overlap in memcpy(0x41f0beb, 0x41f0258, 69141077)
    ==9522==    at 0x402D9A9: memcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
    ==9522==    by 0x8049C13: message_to_buffer (message.c:92)

Вот конкретный код:

case CT_ENTRY://100
{
    int c=(2+2+4+strlen(msg->content.entry->key)-1+4+4+strlen(msg->content.entry->value->data));
    char *offset=malloc(c);
    *msg_buf=offset;
    memcpy(offset,&opcode,2);
    offset+=2;
    memcpy(offset,&ctype,2 );
    offset+=2;
    int ks=strlen(msg->content.entry->key);
    int ksc=host_to_net(ks);
    memcpy(offset,&ksc,4);
    offset+=4;
    memcpy(offset, msg->content.entry->key, ks);
    offset+=ks;
    int l=host_to_net(get_time());
    memcpy(offset,&l,4);
    offset+=4;
    int ds=host_to_net(msg->content.entry->value->datasize);
    memcpy(offset,&ds,4);
    offset+=4;

    // this line here!
    memcpy(offset,msg->content.entry->value->data, msg->content.value->datasize);

    return c;
    break;

Оскорбительная линия

memcpy(offset,msg->content.entry->value->data, msg->content.value->datasize);

Кто-нибудь может объяснить, почему это происходит? Спасибо


person User Conscious    schedule 05.12.2012    source источник
comment
Вы уверены, что значение datasize для 69141077 верное?   -  person Graham Borland    schedule 05.12.2012
comment
Вы копируете почти 70 мегабайт данных, это действительно так?   -  person Some programmer dude    schedule 05.12.2012
comment
Да, похоже, это проблема. Это должно быть всего несколько байтов. Спасибо, что указали мне правильное направление.   -  person User Conscious    schedule 05.12.2012


Ответы (3)


Вы должны использовать memmove вместо memcpy, если исходный и целевой блоки памяти перекрываются.

person Juraj Blaho    schedule 05.12.2012
comment
Но почему они пересекаются? Это совершенно разные переменные. - person User Conscious; 05.12.2012
comment
@UserConscious Даже если переменные разные, области, на которые указывает, могут не совпадать. - person Some programmer dude; 05.12.2012
comment
Итак, как мне решить проблему, так как я хочу скопировать содержимое данных на смещение? - person User Conscious; 05.12.2012
comment
@UserConscious: из вывода valgrind кажется, что размер подозрительно велик ~ 69 МБ. - person Juraj Blaho; 05.12.2012
comment
Вы должны трижды проверить свой код, прежде чем использовать memmove вместо memcpy. Обычно проблема заключается в переполнении буфера, и вы не хотите перекрывать блоки памяти. - person aviggiano; 04.01.2016

Вы говорите memcpy() скопировать 69141077 байт данных. Это выглядит намного больше, чем размер, который вы фактически выделили в offset (если только эти строки действительно огромны).

Итак, это переполнение буфера. Убедитесь, что содержимое msg->content.value->datasize соответствует размеру, который вы рассчитываете при выделении offset.

person Graham Borland    schedule 05.12.2012
comment
Да, похоже, это проблема. - person User Conscious; 05.12.2012

Страница руководства для memcpy() говорит:

Функция memcpy() копирует n байтов из области памяти s2 в область памяти s1. Если s1 и s2 перекрываются, поведение не определено. Приложения, в которых s1 и s2 могут перекрываться, должны вместо этого использовать memmove(3).

person Sunil Bojanapally    schedule 05.12.2012
comment
ОП заявил, что его области не должны перекрываться, поэтому совет использовать memmove() на самом деле не решает проблему. - person Graham Borland; 05.12.2012