我有一个这样的程序:
int *number0 = new int;
int main()
{
int *number1 = new int;
}
我想,两个内存分配都会引入内存泄漏,尽管只有valgrind 抱怨主要功能内的number1。那是为什么?
答案 0 :(得分:4)
Valgrind不是检测是否存在所有可能的内存泄漏的完美工具,而是一种可以检测到一些内存泄漏的有用工具。这意味着valgrind输出不能用于确定特定代码段是否包含任何泄漏。
你的new
都没有相应的delete
s,从这个意义上说,它们都被泄露了。
很可能valgrind认为number0
内存不会被泄露,因为它指向的内存在程序执行结束时是可以访问的。与此相反,number1
超出了范围,因此它指向的内存在程序执行结束时无法访问,因此valgrind认为它被泄露。
答案 1 :(得分:4)
运行此
int *x = new int;
int main()
{
return 0;
}
代码(即没有主要的泄漏,使用g ++ 4.8.1编译)使用valgrind(3.8.1)和(-v --track-origins=yes --leak-check=full --show-reachable=yes
)我得到:
==34301==
==34301== HEAP SUMMARY:
==34301== in use at exit: 4 bytes in 1 blocks
==34301== total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==34301==
==34301== Searching for pointers to 1 not-freed blocks
==34301== Checked 189,064 bytes
==34301==
==34301== 4 bytes in 1 blocks are still reachable in loss record 1 of 1
==34301== at 0x4C2A879: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==34301==
==34301== LEAK SUMMARY:
==34301== definitely lost: 0 bytes in 0 blocks
==34301== indirectly lost: 0 bytes in 0 blocks
==34301== possibly lost: 0 bytes in 0 blocks
==34301== still reachable: 4 bytes in 1 blocks
==34301== suppressed: 0 bytes in 0 blocks
这意味着您还应该关注in use at exit
类别。
看起来valgrind似乎没有错过它,只是把它放在另一个类别中,可能是因为只有当你无法通过任何方式跟踪该地址并释放它时它们才会假设某些东西丢失,但这个变量永远不会丢失
然而:
int *x = new int;
int main()
{
x = new int;
return 0;
}
当您真正丢失已分配的内存时,会被检测为泄漏。
编辑:如记事本manual中所述:
“仍然可以访问”。这包括案例1和2(对于BBB块) 以上。该块的起始指针或起始指针链是 找到。由于块仍然指向,程序员可以,在 至少原则上,在程序退出之前释放它。 “仍然 可到达的“块是非常常见的,可以说也不是问题。所以,通过 默认情况下,Memcheck不会单独报告此类阻止。
正如之前所说,他们确实发现了它,他们只是认为它不那么令人兴奋
答案 2 :(得分:0)
我使用valgrind 3.8.1 / g ++ 4.8.1看到两个泄漏:
$ g++ -o foo -g foo.cc
$ valgrind ./foo
...
==7789== HEAP SUMMARY:
==7789== in use at exit: 8 bytes in 2 blocks
==7789== total heap usage: 2 allocs, 0 frees, 8 bytes allocated
==7789==
==7789== LEAK SUMMARY:
==7789== definitely lost: 4 bytes in 1 blocks
==7789== indirectly lost: 0 bytes in 0 blocks
==7789== possibly lost: 0 bytes in 0 blocks
==7789== still reachable: 4 bytes in 1 blocks
==7789== suppressed: 0 bytes in 0 blocks
在我的测试中,“绝对丢失”的字节位于main
。
答案 3 :(得分:-1)
这个
int *number0 = new int;
不是内存泄漏,因为它在执行结束时被回收。
此配置是[潜在]内存泄漏,因为
int main()
{
int *number1 = new int;
}
代码的其他部分可以调用
main () ;
可以反复调用。