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

Is not calling delete on a dynamically allocated object always a memory leak?

本文关键字:delete 内存 泄漏 调用 动态分配 对象      更新时间:2023-10-16

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

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

我知道内存是由操作系统回收的,但它是泄漏的吗?我相信是的。

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

编辑:我不想开始辩论——"我认为……"不是我想要的那种答案。我最感兴趣的是源代码-C++书籍或网站或任何关于它的内容。

这取决于你如何定义"泄漏"。根据最明显的定义,也是唯一有用的定义,它不是泄漏,至少在应用程序级别。水桶不会因为你有意而漏水允许有限数量的水逸出。实际上,应用程序不会因为有意允许绑定集而失败要在程序结束后继续存在的对象数。

关于记忆泄露,我们对这个词的看法是由"泄漏检查器"着色---像Purify或Valgrind这样的程序。他们的他们的职责是(除其他外)发现漏洞,但他们没有办法知道什么是有意的,什么不是,什么是必然的,什么不是。因此,他们发明了其他定义:一个无法到达的物体已经"泄漏"了(在真实代码中很有可能true),或者在所有已执行静态对象的析构函数已"泄漏"。在里面在后一种情况下,定义显然是错误的无用的但有足够多的情况下,这样的事情是泄漏至少对其发出警告("可能的泄漏")是合理的,前提是有一种方法可以过滤掉具体的案例。(净化和Valgrind认识到,并非所有这些案例都是真正的泄漏为它们的检测提供各种过滤机制。)所有这些很好;我很高兴我们有这样的工具—但是我们不应该允许他们歪曲语言。

最后一点提醒:标准规定标准iostream对象(std::cout等)将永远不会被破坏。所以任何缓冲区他们分配的将(可能)永远不会被释放。当然没有人在他们头脑清醒的人会认为这些"泄漏"。

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

在您的特定示例中,由于main立即退出(有效地),内存被释放回操作系统,因此泄漏没有任何影响。然而,在编写生产代码时,您绝对不应该留下任何泄漏(即使是像上面这样微不足道的泄漏),因为代码可能会转移到不同的函数中,并且泄漏实际上可能会在程序的整个生命周期中传播。

此外,也许最需要考虑的是程序员认为内存泄漏的原因。您应该将内存视为资源,应该根据自己的模型进行管理。考虑阅读本文,其中讨论了一些资源分配和管理模型。考虑RAII(资源获取就是初始化)和智能指针(或者至少考虑智能指针和引用计数的概念)。

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

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

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

a) 它需要内存

b) 它对应用程序不再有用

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

根据这一点,我认为你的样品是内存泄漏。你的样品显示出不加鉴别的泄漏。关键泄漏是持续占用内存,直到应用程序崩溃

这是主观的/有争议的。

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

一旦应用程序终止,应用程序级泄漏就不再存在,因为操作系统清理了应用程序的混乱。也就是说,一旦应用程序遭到核攻击,对操作系统稳定性的威胁就消失了。在适当的操作系统上,应用程序中的内存分配只能产生"应用程序级"泄漏。

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

因此,当I说/写"内存泄漏"时,我指的是应用程序级泄漏-任何未被APP明确删除的内存分配。每一次分配,即使是有意的,也属于这一类。此外,通常内存分配评测器和类似的工具会抱怨你的"故意泄漏",

所以,是的,你的代码有漏洞。

在我看来,即使是故意泄漏,即使你确信操作系统会释放它们,这也是一个坏主意,因为这会鼓励草率的编码,有一天你会无法删除在其析构函数中释放重要内容的类,而这些内容无法由操作系统自动清理。考虑到在普通电脑上windows注册表和临时文件文件夹中留下的垃圾数量,许多程序员经常使用这种技术来处理操作系统没有正确清理的资源。因此,最好的办法是避免泄漏。

是的,存在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.