是不是在动态分配的对象上调用delete总是内存泄漏?

Luc*_*ore 6 c++ memory-leaks memory-management

这里开始的讨论,我想知道以下代码是否有内存泄漏:

int main()
{
   new int();
   //or
   int* x = new int();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道操作系统会回收内存,但无论如何它都是泄漏?我相信它是.

什么定义了内存泄漏?我只能在标准中找到一个参考,并没有太大帮助.

编辑:我不想开始辩论 - "我认为......"不是我正在寻找的那种答案.我最感兴趣的是 - C++书籍或网站或者其他任何关于它的内容.

Jam*_*nze 5

这取决于你如何定义"泄漏".根据最明显的定义,也是唯一有用的定义,它不是泄漏,至少在应用程序级别.水桶不会泄漏,因为您故意让有限量的水逃逸.实际上,应用程序不会失败,因为您有意允许绑定的对象集在程序结束之后持久存在.

关于内存泄漏,我们对这个词的看法已经被"泄密检查员" - 像Purify或Valgrind这样的程序所染色.他们的作用是找到泄漏(除其他外),但他们无法知道什么是故意的,什么不是,什么是约束,什么不是.因此,他们发明了其他定义:一个无法访问的对象已经"泄露"(并且在实际代码中有一个很好的概率,这是真的),或者在执行了所有静态对象的析构函数之后尚未删除的对象"泄露".在后一种情况下,定义显然是错误的,有点无用.但是有足够的情况下,如果有一种过滤掉特定情况的方法,这些事情是泄漏,至少警告它们是合理的("可能的泄漏").(Purify和Valgrind都认识到并非所有这些情况都是真正的泄漏,并为其检测提供了各种过滤机制.)所有这些都是好的 - 我很高兴我们有这样的工具 - 但我们不应该允许他们歪曲语言.

最后一个提醒:标准说标准的iostream对象(std::cout等等)永远不会被破坏.因此,他们分配的任何缓冲区(可能)都不会被释放.当然没有一个心智正常的人会考虑这些"漏洞".


Alo*_*ave 1

第二种情况不是内存泄漏。
这不是泄漏,因为您仍然有一个指向已分配内存的指针。
为了定义内存泄漏,我想坚持大多数内存分析工具(如 valgrind)使用的定义:

内存已分配,随后无法释放,因为程序不再有任何指向已分配内存块的指针。

  • 我想说第二个案例仍然是泄漏;main() 并不特殊,一旦 main 退出,就不再有对动态分配内存的引用(因此它已经泄漏),并且程序仍在运行,直到退出到操作系统> (4认同)
  • +1:一个简短的定义:“运行代码无法访问但仍存储在内存中的对象” (2认同)