可能重复:
在C++中内存泄漏是否属于“未定义行为”问题?
在C++程序中,从new
或new[]
返回的地址上从未调用delete
或delete[]
,是未定义行为还是仅仅是内存泄漏?欢迎提供标准的参考文献(如果有)。
这个问题出现在这里的评论中,我对此有些困惑。
可能重复:
在C++中内存泄漏是否属于“未定义行为”问题?
在C++程序中,从new
或new[]
返回的地址上从未调用delete
或delete[]
,是未定义行为还是仅仅是内存泄漏?欢迎提供标准的参考文献(如果有)。
这个问题出现在这里的评论中,我对此有些困惑。
new
和delete
的语义非常清晰。如果您不调用delete
,那么肯定不会有未定义的行为;事实上,对于单例来说,这是标准做法。我想std::cout
和std::cin
使用new[]
来获取它们的缓冲区(几乎肯定永远不会delete
)。为什么不调用delete
会导致未定义的行为呢?delete
、对使用new
分配的内存调用free
,或者在没有遵循其分配所需的协议的情况下尝试删除对象。[基本生命周期](3.8 对象生命周期)第4段告诉我们:
程序可以通过重用对象占用的存储空间或显式调用具有非平凡析构函数的类类型对象的析构函数来结束任何对象的生命周期。对于具有非平凡析构函数的类类型对象,程序不需要在重用或释放对象所占用的存储空间之前显式调用析构函数;然而,如果没有显式调用析构函数,或者没有使用delete-expression(5.3.5)来释放存储空间,则析构函数不得被隐式调用,任何依赖析构函数产生的副作用的程序都具有未定义行为。
参考 [basic.stc.dynamic.deallocation](也称为 n3337 中的 3.7.4.2),其中只有 4 段。
operator delete
和 operator delete[]
应该是类成员或全局范围内的函数operator delete
和 operator delete[]
的有效签名的精度delete
,取决于用于分配内存的 new
的精度这里绝对没有说明如果分配了存储空间但从未释放会发生什么。
我认为标准并不关心这个问题,因此它更多是“未指定”的而不是“未定义”的。
delete
本身并不会引起未定义的行为。等待析构函数调用永远不会发生。VJovic肯定得到了正确的引用。 - Matthieu M.这只是一个内存泄漏问题。
但我明确记得标准说使用new
和delete[]
,以及new []
和delete
的组合与malloc
或free
的任何组合都是未定义行为。
我不认为标准特别指出如果您未调用delete
,调用new
会导致未定义行为。此外,运行时如何知道您稍后调用delete
还是根本没有调用它?
我不认为标准中有任何契约规定-如果您执行X,则必须随后执行Y,否则就是未定义行为。
operator delete
通常不会将内存返回给操作系统。 - James Kanzenew
抛出std::bad_alloc
异常。(当然,一些系统将堆和栈用于共同空间,使用过多的堆可能会导致栈溢出,这是未定义行为。) - James Kanzenew/new[]
分配对象后没有调用delete/delete[]
,就会出现资源泄漏。如果构造函数已经分配了动态内存,则可能会出现内存泄漏。如果构造函数分配了其他资源,例如信号量锁未释放、文件句柄未释放等,也可能会发生类似的问题。delete
是否仅释放内存。 - Alok Save