C++ 全局分配的内存会发生什么变化?
我有一个这样的程序:C++ 全局分配的内存会发生什么变化?,c++,memory-leaks,global-variables,valgrind,C++,Memory Leaks,Global Variables,Valgrind,我有一个这样的程序: int *number0 = new int; int main() { int *number1 = new int; } 我想,这两种内存分配都会导致内存泄漏,尽管只是valgrind 抱怨主函数中的数字1。为什么会这样?Valgrind不是检测是否存在所有可能的内存泄漏的完美工具,而是可以检测某些内存泄漏的有用工具。这意味着valgrind输出不能用于确定特定代码段是否包含任何泄漏 您的news都没有相应的deletes,从这个意义上讲,它们都是泄漏的 v
int *number0 = new int;
int main()
{
int *number1 = new int;
}
我想,这两种内存分配都会导致内存泄漏,尽管只是valgrind
抱怨主函数中的数字1。为什么会这样?Valgrind不是检测是否存在所有可能的内存泄漏的完美工具,而是可以检测某些内存泄漏的有用工具。这意味着valgrind输出不能用于确定特定代码段是否包含任何泄漏 您的
new
s都没有相应的delete
s,从这个意义上讲,它们都是泄漏的
valgrind可能认为number0
内存没有泄漏,因为它指向的内存在程序执行结束时是可访问的。与此相反,number1
超出范围,因此在程序执行结束时无法访问它指向的内存,因此valgrind认为它泄漏了。
int *number0 = new int;
不是内存泄漏,因为它在执行结束时被回收
此配置是[潜在]内存泄漏,因为
int main()
{
int *number1 = new int;
}
代码的其他部分可以调用
main () ;
并且可以重复调用它。运行此
int *x = new int;
int main()
{
return 0;
}
使用valgrind(3.8.1)和(-v--track origins=yes--leak check=full--show reachable=yes
)编写代码(即主文件中没有泄漏,使用g++4.8.1编译):
这意味着您还应该注意退出时使用的类别
valgrind似乎没有漏掉它,只是把它放在了另一个类别中,可能是因为他们认为只有在你无论如何都无法找到那个地址并发布它时,才会丢失某些东西,但这个变量永远不会丢失
然而,这是:
int *x = new int;
int main()
{
x = new int;
return 0;
}
被检测为泄漏,因为您确实无法跟踪已分配的内存
编辑:如Mem检查中所述:
“仍然可以到达”。这包括案例1和案例2(适用于BBB区块)
在上面指向块的起始指针或起始指针链是
建立由于块仍然指向,程序员可以
至少在原则上,在程序退出之前释放它。“还是
“可到达”块非常常见,可以说不是问题。那么
默认情况下,Memcheck不会单独报告此类块
因此,正如在他们检测到之前所指出的,他们只是认为这不太令人兴奋我使用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
中。这并不重要,因为进程终止时会释放任何内存。我猜valgrind认为由全局变量指向的内存不是memleak。在你得出结论之前,可以做一些类似number0的事情,但是,请记住,如果是类类型而不仅仅是int
,则不会调用它的析构函数(在这种情况下,valgrind可能会抱怨?)@dlf:正是我的问题:我认为,由于没有valgrind警告,该对象的析构函数(由*number0表示)已经以某种方式自动调用,而我现在知道的情况当然不是这样。我也不认为让进程终止处理手动分配的内存是可以的。我不知道为什么,但这让我感到不寒而栗。在C++
程序中调用main()
是不合法的。(参见Base>基本[St.Me])/3代码>代码>:“函数main不应在程序内使用。”它不必是C++程序调用C++例程。您恐怕没有任何一个程序,但在每个类别中只有一个(在绝对丢失的类别中有一个代码> int /代码>(4字节),在一个仍然可到达的类别中只有一个)。我认为这正是OP所要问的,也就是说,为什么valgrind将那些看似相同的泄漏分为不同的类别。哦,现在我明白了为什么复数形式是有意义的:)
$ 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