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

rom*_*ovs 4 c++ memory-leaks memory-management

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

TGraph* A = new TGraph(...);
Run Code Online (Sandbox Code Playgroud)

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

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

Alo*_*ave 9

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

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

请注意,如果delete需要调用的对象的析构函数执行一些非平凡的操作,并且您的程序依赖于它产生的副作用,那么您的程序将成为Undefined Behavior [Ref 1]的牺牲品.一旦发生这一切,所有投注都将被取消,您的计划可能会显示任何行为.

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

因此,通过调用deletedelete []退出程序之前始终取消分配所有分配是一种好习惯.


[参考1] C++ 03标准3.8第4段:

".... 如果没有对析构函数的显式调用或者如果没有使用delete-expression(5.3.5)来释放存储,则不应该隐式调用析构函数,并且任何依赖于生成的函数的程序都会生成析构函数具有未定义的行为."

  • @romeovs:请注意,仅仅因为你*可以*做某事并不意味着你*应*.不删除东西仍然是不好的形式.虽然有人想知道为什么如果它不能在范围结束时存活,那么你根本就可以分配它. (3认同)

Pét*_*rök 7

IMO最好始终打电话delete:

  • 使其成为一种自动习惯,使其在真正需要时不太可能忘记它
  • 覆盖需要释放非内存资源(套接字,文件句柄,...)的情况 - 这些不会被操作系统自动释放
  • 当有问题的代码可能超出main范围时,以迎合将来的重构