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

时间:2012-03-29 08:19:24

标签: c++ memory-management memory-leaks

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

int main()
{
   new int();
   //or
   int* x = new int();
   return 0;
}

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

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

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

6 个答案:

答案 0 :(得分:5)

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

关于内存泄漏,我们对这个词的看法已经存在 由“泄漏检查员”着色 - 像Purify或Valgrind这样的程序。其 角色是找到泄漏(除其他外),但他们没有办法 知道什么是有意的,什么不是,什么是约束,什么 不是。因此他们发明了其他定义:一个无法到达的对象 已经“泄露”(并且在实际代码中存在很大的可能性 true),或者在所有之后没有被删除的对象 已执行的静态对象的析构函数已“泄露”。在 后一种情况,定义显然是错误的,而且有点 无用。但是有足够的情况会发生这样的事情 至少提醒他们(“可能的泄漏”)是合理的 有一种过滤特定情况的方法。 (Purify和 Valgrind意识到并非所有这些案件都是真正的泄漏,并且 为它们的检测提供各种过滤机制。)所有这些 很好也很好 - 我很高兴我们有这样的工具 - 但是 我们不应该让他们歪曲语言。

最后一个提醒:标准说标准的iostream 对象(std::cout等)永远不会被破坏。所以任何缓冲区 他们分配意志(可能)永远不会被释放。当然没有人在他们的 正确的思想会考虑这些“泄漏”。

答案 1 :(得分:4)

上面的代码确实有漏洞。但更重要的是,如果不是分配int,而是分配了一个特殊对象,比如服务器连接对象,如果你从未正确清理并调用delete,那么对象的析构函数永远不会运行,如果您的服务器连接需要执行特殊的清理代码(写入文件等)可能很重要。

在您的具体示例中,泄漏是无关紧要的,因为main立即退出(有效)并且内存被释放回操作系统。但是,在编写生产代码时,你绝对不应该留下任何泄漏(即使是上面那么简单),因为代码可能会被转移到另一个函数中,泄漏实际上可能会在程序生命周期内传播。

此外,最重要的事情可能是程序员认为是内存泄漏的。您应该将内存视为应根据您自己的模型管理的资源。考虑阅读this article,其中讨论了一些资源分配和管理模型。考虑RAII(资源获取是初始化)和智能指针(或者至少是智能指针的思想和引用计数的想法)。

答案 2 :(得分:1)

我会以这种方式定义内存泄漏

a)需要记忆

b)它对应用程序没有用处

c)它不再可访问,因此不再可删除

根据这个,我会判断你的样本是内存泄漏。 您的样本显示出不加批判的泄漏。 严重泄漏是持续记忆,在应用程序崩溃之前可能发生的事情

答案 3 :(得分:1)

这是主观的/有争议的。

在我看来,有两个级别的资源(内存是操作系统提供的资源之一)泄漏:操作系统级别和应用程序级别。请注意,名称是自定义的,可能有更合适的技术术语。

应用程序终止后,应用程序级别的泄漏就不再存在,因为操作系统会清除应用程序的混乱。即一旦应用程序被破坏,对操作系统稳定性的威胁就会消失。在体面的操作系统中,应用程序中的内存分配只能产生“应用程序级”泄漏。

应用程序终止后,操作系统级别的泄漏将不再存在。通常,其他一些资源属于该类别(文件),但不属于内存。但是,我不能保证没有没有清理泄漏内存的操作系统/平台。按照墨菲定律,即使在今天也可能会使用这样的平台。

所以当说/写“内存泄漏”时,我说的是应用程序级泄漏 - 任何内存分配,而APP没有明确删除。每一次分配,甚至是有意的,都归入类别。此外,通常内存分配分析器和类似工具会抱怨您的“故意泄密”,

所以,是的,您的代码有泄漏。

在我看来,即使你确定操作系统会释放它们也会故意泄密,这是一个坏主意,因为它鼓励编写代码,有一天你将无法删除在其析构函数中发布重要内容的类无法自动清理操作系统。考虑到普通PC上的Windows注册表和临时文件文件夹中剩余的垃圾量,许多程序员经常将该技术用于未被OS正确清理的资源。因此,最好的办法是避免泄漏。

答案 4 :(得分:1)

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

  

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

答案 5 :(得分:-1)

是的,有4个字节的泄漏,因为new分配的内存不是delete d,并且在应用程序的生命周期中它是泄漏。

从这个链接:

http://www.yolinux.com/TUTORIALS/C++MemoryCorruptionAndMemoryLeaks.html

Memory leak description: Memory is allocated but not released causing an application to consume memory reducing the available memory for other applications and eventually causing the system to page virtual memory to the hard drive slowing the application or crashing the application when than the computer memory resource limits are reached. The system may stop working as these limits are approached.