使用运算符new / malloc分配的内存块是否可以在程序执行结束后持续存在?

时间:2012-07-08 13:10:00

标签: c++ c dynamic-memory-allocation

  

可能重复:
  When you exit a C application, is the malloc-ed memory automatically freed?

当我读到关于在C / C ++中动态内存分配时分别使用delete / free是多么强制时,我才想到这个问题。我想如果内存分配持续超出我的程序执行终止,那么是的,它是强制性的;否则,为什么我要担心释放分配的空间?操作系统是否会在进程终止时自动释放它?我是对的吗? 我的问题是可以

int *ip = new int(8);

超出我的程序终止?

9 个答案:

答案 0 :(得分:15)

简短回答:不。

答案很长:没有。除非你做的工作要做,否则C ++永远不会留下记忆。释放内存的原因是:

如果你没有释放内存,但继续分配它,你会在某个时候耗尽。一旦你用完了,几乎任何事情都可能发生。在Linux上,可能会激活OOM杀手并且您的进程被终止。也许操作系统会将您完全归档到磁盘。如果你使用足够的内存,也许你给Windows框一个蓝屏。它几乎可以被认为是未定义的行为。此外,如果你泄漏内存,它只是在那里选址,未使用,未发布,没有人可以使用它,直到你的进程终止。

还有另一个原因。当您向分配器释放内存时,分配器可能会将其保留,但只需将其标记为可用。这意味着下次你需要记忆时,它已经坐在那里等着你。这意味着内核调用内存的次数越少,性能就越高,因为上下文切换效率非常低。

编辑:C和C ++标准甚至不保证终止后操作系统将清理内存。许多操作系统和编译器可能,但不能保证。尽管如此,所有主要的桌面和移动操作系统(除了可能是DOS和一些非常旧的嵌入式系统)都会在它之后清理进程内存。

答案 1 :(得分:6)

在程序退出之前,您无需将内存释放回操作系统,因为操作系统将回收在进程终止时分配给进程的所有内存。如果在完成流程之前分配了所需的对象,则不必将其释放。

话虽如此,仍然是一个好主意,无论如何释放内存:如果你的程序经常使用动态内存,你几乎肯定需要运行内存分析器来检查内存泄漏。探查器将告诉您最后没有释放的块,您需要记住忽略它们。将泄漏次数保持为零会好得多,原因同样是可以消除100%的编译器警告。

答案 2 :(得分:4)

任何好的操作系统都应该在进程退出时清理所有资源; “总是免费的你分配的”原则对两件事情有好处:

  1. 如果您的程序泄漏内存但从未退出(守护程序,服务器......),连续泄漏的内存将严重浪费RAM。

  2. 在你的程序终止之前你不应该推迟释放所有内存(比如Firefox有时会注意到它需要多长时间才能退出?) - 重点是最小化你分配内存的时间;即使您的程序继续运行,您应该在完成后立即释放已分配的RAM。

答案 3 :(得分:4)

1)当你请求离开堆时,释放你的记忆。内存泄漏永远不是一件好事。如果它现在没有伤害你,它可能会在未来发展。

2)C或C ++无法保证您的操作系统会为您清理内存。你可能有一天会在一个系统上进行编程,事实上,这个系统却没有。或者更糟糕的是,您可能正在将不关心内存泄漏的代码移植到这个新平台。

答案 4 :(得分:4)

对于历史记录:旧Amiga计算机(“AmigaOS”)使用的操作系统没有现在假设的完整内存管理(除非Amiga不再流行时发布的某些更新版本)。

CPU没有MMU(内存管理单元),因此每个进程都可以访问所有物理内存。因此,当两个进程想要共享一些信息时,他们只能交换指针。操作系统甚至鼓励这种做法,它在消息传递方案中使用了这种技术。

但是,这使得无法跟踪哪个进程拥有哪个内存部分。因为操作系统没有释放完成的进程(或任何其他资源,事实上)的内存。因此,释放所有分配的内存至关重要。

答案 5 :(得分:3)

如果您非常确定 从不 需要在程序的生命周期内释放内存,从技术上讲,跳过空闲/删除可能没问题。 Linux,Windows等操作系统将在进程结束时释放分配的内存。但实际上,您几乎不会假设您分配的内存不需要在进程的生命周期内释放。考虑到代码的可重用性,可维护性和可扩展性,始终释放在适当位置分配的所有内容是一种很好的做法。

答案 6 :(得分:2)

这是一个有趣的问题。我的原始问题是你是否可以在程序完成后访问内存,但是在第二次阅读之后,我看到你想知道为什么应该释放内存。

您可以释放动态分配的内存,因为如果您不这样做,操作系统和其他进程将耗尽,您将不得不重新启动。

我认为您可能希望在程序完成后访问该内存,所以我的猜测是即使您写出了动态分配的内存块的起始地址和长度 - 到控制台或文件 - 该地址可能程序完成后无效。

这是因为当您的程序运行时,您有一个虚拟页面地址,在程序完成后,您可能无法在没有内核权限的情况下触摸该虚拟页面地址。或者,还有另一个原因。

答案 7 :(得分:1)

它肯定不会超出程序终止。这个想法是在不再需要的时候释放内存,这样你的程序就不会浪费内存(它不会消耗更多的内存),或者更糟糕的是,内存不足(取决于你的分配模式)

答案 8 :(得分:0)

你必须担心它,因为想象你在许多地方分配了大量内存而没有释放它。一旦分配了内存,它就占用了一部分无法再分配的内存。这将导致每次可用内存量变得越来越小,因为您无法释放它。在某些时候,内存将耗尽。即使在程序终止时释放内存,也可以想象你的程序一次运行几周,不断分配内存但从不释放内存。内存是一种有限的资源,在使用动态分配时需要负责。