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

2021-12-24 00:00:00 memory-management memory-leaks c++

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

When using dynamically allocated objects in C++ eg:

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

应该总是delete这些,否则对象可能仍然在内存中控制权交还给父作用域.虽然我可以理解为什么这对于程序的子作用域和子例程来说是正确的,但对于 main 作用域是否同样计数?

One should always delete these because otherwise the objects might still be in memory when control is handed back to the parent scope. While I can see why this is true for subscopes and subroutines of a program, does the same count for the main scope?

我是否必须删除main()中动态构建的对象?这对我来说有点多余的原因是,当main结束时,程序也结束了,所以不必担心内存泄漏.

Am I obliged to delete objects that were dynamically built inside main()? The reason why this seems a bit redudant to me is that when main ends, the program also ends, so there is no need to worry about memory leaks.

推荐答案

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

Most of the modern OS always reclaim back all memory they allocated to a program(process).
The OS doesn't really understand if your program leaked memory it merely takes back what it allocatted.

但手头还有更大的问题,而不仅仅是失忆:

But there are bigger issues at hand than just the memory loss:

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

Note that if the destructor of the object whos delete needs to be called performs some non-trivial operation and your program depends on the side effects produced by it then your program falls prey to Undefined Behavior[Ref 1]. Once that happens all bets are off and your program may show any beahvior.

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

Also, An OS usually reclaims the allocated memory but not the other resources, So you might leak those resources indirectly. This may include operations dealing with file descriptors or state of the program itself etc.

因此,在退出程序之前始终通过调用 deletedelete [] 来释放所有分配是一个好习惯.

Hence, it is a good practice to always deallocate all your allocations by calling delete or delete [] before exiting your program.

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

"....如果没有显式调用析构函数或者如果没有使用删除表达式(5.3.5)来释放存储,则不应隐式调用析构函数,任何程序取决于析构函数产生的副作用有未定义的行为."

相关文章