Насколько серьезна следующая утечка памяти, показанная Valgrind - PullRequest
4 голосов
/ 06 августа 2011

После написания тысяч строк кода я использую valgrind и с ужасом вижу количество ошибок.Просто раньше использовал GDB.Большинство моих ошибок связаны со строковыми функциями.Я публикую часть.Я понимаю, что ошибка происходит, потому что strlen не считает завершающий NULL, тогда как strcpy добавляет его.Насколько это серьезно?Мне действительно нужно их исправить?Я могу это исправить, но волнуюсь, может ли это привести к большему количеству ошибок, так как мой код не учел это, когда я это написал.

Скопирует ли strcpy завершающий NULL, даже если для него не зарезервировано пространство?

t.write_length = (strlen("NA\n");/*Line number 116*/
t.data = malloc(strlen("NA\n");/*117*/
strcpy(t.data,"NA\n");/*118*/

Valgrind:

==3287== Invalid write of size 1
==3287==    at 0x400764E: memcpy (mc_replace_strmem.c:497)
==3287==    by 0x804A714: log_txn_commit (Log_manager.c:118)
==3287==    by 0x8049D3C: on_txn_commit (TxFS_manager.c:85)
==3287==    by 0x804939E: handler (Reader.c:139)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)
==3287==  Address 0x403282b is 0 bytes after a block of size 3 alloc'd
==3287==    at 0x4005BDC: malloc (vg_replace_malloc.c:195)
==3287==    by 0x804A6F5: log_txn_commit (Log_manager.c:117)
==3287==    by 0x8049D3C: on_txn_commit (TxFS_manager.c:85)
==3287==    by 0x804939E: handler (Reader.c:139)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)

Ответы [ 4 ]

8 голосов
/ 06 августа 2011

Это серьезная проблема с перезаписью памяти. Ваш код должен быть

t.write_length = strlen("NA\n");/*Line number 116*/
t.data = malloc(t.write_length + 1);
strcpy(t.data,"NA\n");

и требует исправления наверняка. strcpy() добавит завершающий '\0', для которого нет места.

Чтобы избежать переполнения, размер массива, указанного адресатом, должен быть достаточно длинным, чтобы содержать ту же строку C, что и источник (включая завершающий нулевой символ), и не должен перекрываться в памяти с источник.

Всегда серьезно относитесь к советам Вальгринда!

5 голосов
/ 06 августа 2011

Вы всегда хотите исправить ошибки, о которых сообщает Valgrind.Неверные записи приводят к неожиданному поведению, которое по определению не является тем, что должна делать ваша программа.В зависимости от того, как ваша программа размещена в памяти, вы можете перезаписывать другие важные переменные или не полностью писать то, что ожидаете.

Если исправление приводит к большему количеству ошибок в вашем коде, это означает, что другие частиВаш код ошибочен, а не отчет Valgrind.Вы должны исправить эту ошибку, и если это приведет к дальнейшим сообщениям об ошибках, вы исправите и их.Игнорируйте неверные ошибки чтения / записи на свой страх и риск.

4 голосов
/ 06 августа 2011

Да, вам всегда нужно malloc(strlen(str) + 1) байт для строки (для этого досадного нулевого терминатора). Или более простой способ - использовать strdup.

2 голосов
/ 06 августа 2011

Потенциально довольно серьезно, и вы должны это исправить. Попробуйте использовать либо strdup(), если вам нужен конечный ноль, либо memcpy(), если вам не нужен конечный ноль.

...