C ++是否有必要在主范围的末尾删除动态分配的对象?

时间:2012-04-23 09:21:32

标签: c++ memory-management memory-leaks

在C ++中使用动态分配的对象时,例如:

TGraph* A = new TGraph(...);

总是应该delete这些因为否则对象可能仍然在内存中 控制权交还给父范围。虽然我可以看到为什么对于程序的子范围和子程序来说这是正确的,main范围的计数是否相同?

我是否有义务在delete内动态构建main()个对象?这对我来说似乎有点减少的原因是当main结束时,程序也会结束,所以不必担心内存泄漏。

7 个答案:

答案 0 :(得分:9)

大多数现代操作系统总是回收他们分配给程序(进程)的所有内存 操作系统并不真正了解你的程序是否泄漏了内存,它只会收回它所分配的内容。

但是手头上存在的问题不仅仅是记忆丧失:

请注意,如果需要调用delete的对象的析构函数执行一些非平凡的操作,并且您的程序依赖于它产生的副作用,那么您的程序将成为未定义行为< / strong> [参考1] 。一旦发生这一切,所有投注都将被取消,您的计划可能会显示任何行为。

此外,操作系统通常会回收已分配的内存,但不回收其他资源,因此您可能会间接泄漏这些资源。这可能包括处理文件描述符的操作或程序本身的状态等。

因此,最好在退出程序之前通过调用deletedelete []来取消分配所有分配。


[参考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)

最佳做法:

  1. 请勿使用new,请使用自动分配
  2. 当需要动态分配时,使用RAII确保自动清理
  3. 您永远不必在应用代码中写delete

    在此,为什么要为new调用TGraph

    TGraph A(...);
    

    效果更好:减少担忧!