即使在修复泄漏后,Valgrind也会显示相同的内存泄漏

时间:2011-08-24 09:19:14

标签: c++ valgrind

我们正试图找出在Linux上运行的C ++应用程序中的内存泄漏。我们正在使用Valgrind 3.6.0并且能够获得一些“绝对丢失”的堆栈。在报告中,它还给出了“绝对丢失”字节的总数。

我们必须包含的修复方法是:将delete ptr更改为delete[] ptr,其中ptr指向堆上的位置数组。

请注意,ptr持有大量内存。我们同样修复了许多其他删除。因此,我们预计泄漏会减少。

但是在修复之后,奇怪的是Valgrind在摘要中仍然报告了与之前相同的泄漏次数。

==00:00:15:13.661 14014== LEAK SUMMARY:
==00:00:15:13.661 14014==    definitely lost: 236 bytes in 8 blocks
==00:00:15:13.661 14014==    indirectly lost: 22,113 bytes in 17 blocks
==00:00:15:13.662 14014==      possibly lost: 695,006 bytes in 47 blocks
==00:00:15:13.662 14014==    still reachable: 2,056,059 bytes in 732 blocks
==00:00:15:13.662 14014==         suppressed: 0 bytes in 0 blocks

有人能否了解一下Valgrind的这种行为? 我们正在使用所有正确的选项来调用mem_check工具等。

1 个答案:

答案 0 :(得分:1)

答案是,首先使用错误的delete类型释放的块从未包含在泄漏报告中,因为valgrind意识到错误的delete使用并报告并释放了整个区块。

我们可以通过一个简单的程序看到这种效果:

int main(int argc, char **argv)
{
  int *x = new int[20];

  delete x;

  return x != 0;
}

当在valgrind下运行时,报告:

==12212== Mismatched free() / delete / delete []
==12212==    at 0x61DCD1FC: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12212==    by 0x4005AC: main (x.c:7 in /tmp/x)
==12212==  Address 0x61fd4040 is 0 bytes inside a block of size 80 alloc'd
==12212==    at 0x61DCD967: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12212==    by 0x40059C: main (x.c:5 in /tmp/x)
==12212== 
==12212== 
==12212== HEAP SUMMARY:
==12212==     in use at exit: 0 bytes in 0 blocks
==12212==   total heap usage: 1 allocs, 1 frees, 80 bytes allocated
==12212== 
==12212== All heap blocks were freed -- no leaks are possible

所以它已经告诉过你使用了delete的错误,但后来报告没有泄漏,因为一旦它意识到你的错误,它实际上释放了整个块。

它报告泄密的事情是你没有尝试过的东西,如果你读过泄密报告之前的漏洞报告,那么valgrind就会告诉你确切的位置所有泄露的内存都已分配,您应该能够跟踪这些泄漏并修复它们。