Valgrind显示以下内存泄漏有多严重

时间:2011-08-06 02:42:53

标签: c linux valgrind

在编写了数千行代码之后,我使用了valgrind并且惊恐地看到了错误的数量。之前只是使用GDB。我的大多数错误都是使用字符串函数。我张贴了一部分。我理解错误正在发生,因为strlen不计算尾随的NULL,而strcpy添加它。有多严重?我真的需要修理它们吗?我可以解决它,但担心如果这可能会导致更多的错误,因为我的代码并没有记住,当我作为wriitng时。

即使没有为它保留空间,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 个答案:

答案 0 :(得分:8)

这是一个严重的内存覆盖问题。你的代码应该是

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

并且需要确定。 strcpy()会附加没有余地的终结'\0'

  

为避免溢出,目标指向的数组大小应为   足够长,可以包含与源相同的C字符串(包括   终止空字符),并且不应该在内存中重叠   源。

始终认真对待Valgrind的建议!

答案 1 :(得分:5)

您总是希望修复Valgrind报告的错误。无效写入会导致意外行为,根据定义,这不是您的程序应该执行的操作。根据程序在内存中的布局方式,您可能会覆盖其他重要变量,或者没有完全写出您期望的内容。

如果修复此问题会导致代码中出现更多错误,这意味着代码的其他部分出错,而不是Valgrind的报告。您应该修复此错误,如果这会导致报告更多错误,您也可以修复这些错误。忽略无效的读/写错误,这是你自己的危险。

答案 2 :(得分:4)

是的,对于一个字符串(对于那个讨厌的null终止符),总是需要malloc(strlen(str) + 1)个字节。或者更简单的方法是使用strdup

答案 3 :(得分:2)

可能非常严重,你应该修复它。如果需要尾随空值,请考虑使用strdup();如果不需要尾随空值,请考虑使用memcpy()