我知道,如果我不使用 delete/free 释放分配的内存,我最终会出现内存泄漏。我的问题是:如果我的程序被终止,操作系统是否会为我释放内存,即使我没有?
5 回答
简而言之,是的。
当进程终止时,所有映射到进程地址空间的存储都将返回给操作系统,即使您没有显式释放它。
在 C++ 中,删除将导致调用对象的析构函数。这个析构函数可能会处理除释放内存之外的事情。它可能会关闭文件、减少引用计数等。因此,如果您忽略删除动态分配的对象,不知道会出现什么问题。
内存是否泄漏取决于操作系统。在大多数操作系统的情况下,一旦您的程序运行的进程退出操作系统,操作系统就会简单地回收它分配给进程的内存。
它还有另一个重要方面。new
导致调用类构造函数并delete
导致调用析构函数。因此,如果您调用new
并且从未调用过,delete
那么除了在程序退出后可能/可能不存在的所谓内存泄漏之外,还有一个附加条件是,如果特定类的析构函数调用了一些具有副作用的代码,那么它会导致未定义的行为。
所以答案取决于,你可能有:
- 内存泄漏(取决于操作系统行为)
- 未定义的行为(取决于析构函数中的代码是否有副作用)
C++11 标准 3.8 对象生命周期:
第 4 段:
程序可以通过重用对象占用的存储空间或通过显式调用具有非平凡析构函数的类类型对象的析构函数来结束任何对象的生命周期。对于具有非平凡析构函数的类类型的对象,在重用或释放对象占用的存储空间之前,程序不需要显式调用析构函数;但是,如果没有显式调用析构函数,或者如果没有使用删除表达式 (5.3.5) 来释放存储,则不应隐式调用析构函数以及依赖于析构函数产生的副作用的任何程序具有未定义的行为。
如果您不调用delete
- 将不会调用任何析构函数。如果任何析构函数关闭文件、向数据库写入内容等,则不会执行这些操作
您的问题似乎是基于对内存如何工作的天真理解,这与现代操作系统的工作方式不相符。术语“内存”含糊不清,您真的应该分别考虑物理内存(RAM)和虚拟内存(地址空间)。
当您调用 时malloc
,您会在进程中保留地址空间。如果操作系统认为这样做是明智的,它会用物理 RAM 支持该地址空间。如果操作系统想将该 RAM 用于其他用途,它只是这样做。你无法阻止它。因此,您不必担心 RAM。操作系统足够智能,即使内存没有被某个进程专门释放,它也可以始终将其充分利用。
虚拟内存,仅仅是地址空间,并不稀缺。一旦您的进程终止,您的地址空间就会不复存在。所以没有什么可以退货的。
一旦内存无法访问,操作系统就别无选择,只能将其释放。