14

可能重复:
当您退出 C 应用程序时,malloc-ed 内存是否会自动释放?

当我在阅读有关在 C/C++ 中的动态内存分配方面分别使用 delete/free 的强制性时,我想到了这个问题。我想如果内存分配在我的程序执行终止之后仍然存在,那么是的,它是强制性的;否则,我为什么要担心释放分配的空间?操作系统不会在进程终止时自动释放它吗?我有多正确?我的问题是可以

int *ip = new int(8);

在我的程序终止之后仍然存在?

4

9 回答 9

15

简短的回答:没有。

长答案:不。C++ 永远不会持久化内存,除非你努力让它这样做。释放内存的原因是这样的:

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

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

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

于 2012-07-08T13:17:12.953 回答
6

您不需要在程序退出之前将内存释放回操作系统,因为操作系统将在进程终止时回收已分配给您的进程的所有内存。如果您分配一个直到您的过程完成所需的对象,您不必释放它。

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

于 2012-07-08T13:17:44.413 回答
5

1)当您请求时释放您的内存(如果不在堆中)。内存泄漏从来都不是一件好事。如果它现在不伤害你,它可能会在路上。

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

于 2012-07-08T13:18:54.427 回答
5

历史记录:旧 Amiga 计算机(“AmigaOS”)使用的操作系统并没有像现在假设的那样具有完整的内存管理(可能在 Amiga 不再流行时发布的一些更高版本除外)。

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

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

于 2012-07-08T14:50:37.087 回答
4

任何好的操作系统都应该在进程退出时清理所有资源;“总是释放你分配的东西”的原则有两个好处:

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

  2. 您不应该推迟释放所有内存,直到您的程序终止(就像 Firefox 有时那样 - 注意到它需要多长时间才能退出?) - 关键是最小化您分配内存的时间;即使您的程序继续运行,您也应该在完成后立即释放分配的 RAM。

于 2012-07-08T13:16:51.667 回答
4

如果您非常确定在程序的生命周期内永远不需要释放内存,从技术上讲,跳过释放/删除可能是可以的。Linux、Windows 等操作系统将在进程结束时释放分配的内存。但在实践中,您几乎永远不能假设您分配的内存不需要在进程的生命周期内释放。牢记代码的可重用性、可维护性和可扩展性,最好始终在适当的位置释放分配的所有内容。

于 2012-07-08T13:20:58.647 回答
2

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

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

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

那是因为当你的程序运行时,你有一个虚拟页面地址,在程序完成后,如果没有内核权限,你可能无法访问该地址。或者,还有其他原因。

于 2012-07-08T13:15:17.553 回答
1

它肯定不会在程序终止之后继续存在。这个想法是在不再需要时释放内存,这样您的程序就不会浪费内存(它不会消耗超过它真正需要的内存),或者更糟糕的是,不会耗尽内存(取决于您的分配模式)

于 2012-07-08T13:17:14.280 回答
0

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

于 2012-07-08T13:14:47.503 回答