我们正试图找出在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工具等。
答案 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
就会告诉你确切的位置所有泄露的内存都已分配,您应该能够跟踪这些泄漏并修复它们。