在C ++中使用动态分配的对象时,例如:
TGraph* A = new TGraph(...);
总是应该delete
这些因为否则对象可能仍然在内存中
控制权交还给父范围。虽然我可以看到为什么对于程序的子范围和子程序来说这是正确的,main
范围的计数是否相同?
我是否有义务在delete
内动态构建main()
个对象?这对我来说似乎有点减少的原因是当main
结束时,程序也会结束,所以不必担心内存泄漏。
答案 0 :(得分:9)
大多数现代操作系统总是回收他们分配给程序(进程)的所有内存 操作系统并不真正了解你的程序是否泄漏了内存,它只会收回它所分配的内容。
但是手头上存在的问题不仅仅是记忆丧失:
请注意,如果需要调用delete
的对象的析构函数执行一些非平凡的操作,并且您的程序依赖于它产生的副作用,那么您的程序将成为未定义行为< / strong> [参考1] 。一旦发生这一切,所有投注都将被取消,您的计划可能会显示任何行为。
此外,操作系统通常会回收已分配的内存,但不回收其他资源,因此您可能会间接泄漏这些资源。这可能包括处理文件描述符的操作或程序本身的状态等。
因此,最好在退出程序之前通过调用delete
或delete []
来取消分配所有分配。
[参考1] C ++ 03标准3.8第4段:
“.... 如果没有对析构函数的显式调用,或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何程序都不能取决于析构函数产生的副作用具有未定义的行为。“
答案 1 :(得分:7)
IMO最好始终正确地呼叫delete
:
main
范围时,答案 2 :(得分:3)
是的,您应该致电delete
,至少是因为这是最佳做法。如果你的析构函数中有重要的逻辑,那么你应该调用delete
的另一个原因。
更正:如果程序依赖于析构函数中的逻辑,则不显式调用delete
会导致未定义的行为。
答案 3 :(得分:0)
这对我来说似乎有点减少的原因是当主要结束时, 程序也结束了,所以没有必要担心内存 泄漏。
你是对的,但考虑一下:你创建了一个类对象,它打开了与远程数据库的连接。你的程序完成后,你应该告诉数据库“我已经完成了,我将要断开连接”,但如果你不能正确地调用删除,就不会发生这种情况。
答案 4 :(得分:0)
最佳做法是取消分配已分配的内存。你应该记住堆内存是有限的,只是在你的程序运行时分配没有解除分配可能会为其他/或同一个程序运行堆空间(如果它的某种守护程序是运行的)很长一段时间)需要堆。
当然,在程序执行结束时,操作系统将回收内存。
答案 5 :(得分:0)
我看到你正在使用ROOT(CMS家伙?)。我认为ROOT会照顾这个并清理,不是吗?
答案 6 :(得分:0)
最佳做法:
new
,请使用自动分配您永远不必在应用代码中写delete
。
在此,为什么要为new
调用TGraph
?
TGraph A(...);
效果更好:减少担忧!