[有人觉得“退出前不必释放所有内存”的说法令人困惑,但同时又认为“显式释放内存是一种良好的编程实践”。这是我的回复。]

发件人:Steve Summit
日期:2001年3月24日星期六 14:27:06 -0800
主题:Re: C-FAQ 书籍勘误

嗯,这个情况(不幸的是)本质上有点复杂。我会说你“不必”释放内存,很多人也会同意我的观点,但可能也有一些人会持不同意见,他们会说记住释放内存实际上是程序员的责任。大多数“真正的”操作系统都会认真对待它们在程序退出时回收所有资源的责任;在这些操作系统下,大家都会同意,如果一个程序在退出前忽视释放所有内存,并且这些内存因此变得无法挽回地丢失,那将是一个严重的错误,是操作系统本身的错误,而不是应用程序的错误。

但另一方面,据说有一些系统,无论出于何种原因,并不能完全回收内存,而在这些系统下,程序员要么必须显式释放所有内存,要么就只能忍受其永远丢失(或者直到下次重启,大概是这样)。

最后,抛开操作系统保证做什么或不做什么不谈,还涉及负责任的程序员应该做什么的问题。在某些情况下,花费精力释放所有(或大部分)内存是一个非常好的主意。在另一些情况下,释放内存显然是得不偿失——如果一个程序拥有大量复杂、相互关联、动态分配的内存结构,并且程序即将退出,那么尽最大努力释放所有内存除了增加程序的代码空间占用、稍微延长运行时间以及增加出错的可能性之外,可能不会带来任何好处。(你愿意看到一个程序在尝试退出时崩溃,并且发现它在尝试释放操作系统本来就会回收的某些内存时崩溃吗?)

> 也许,最后一段应该更强调地说,在
> 某些情况下,显式释放内存很重要(提供
> 代码段示例?),但在其他情况下,可能不
> 是个好主意(提供示例)。

如果你使用的是一个在程序退出时不会回收内存的有缺陷的操作系统,你必须自己释放内存。如果你的程序是一个永不退出的长期运行的服务器,你必须在你完成使用内存时释放它,否则所有可用内存最终都会“泄漏掉”。如果你正在编写一个只做一项工作然后退出的程序,但将来可能会被重写以长时间运行并执行多次任务,那么今天就编写必要的内存释放代码可能会更容易,因为当时数据结构及其内存分配策略都还新鲜在你的脑海里。最后,如果你正在使用一个自动化的“泄漏跟踪”工具,该工具会警告你任何你分配但未释放的内存块,并且你正试图用它来追踪代码中一个部分中不断分配和释放内存的内存泄漏,你可能会发现“修复”所有分配是有用的,也就是说,显式释放你曾经分配过的每一小块内存,即使是那些你本来可以满足于操作系统隐式清理的一次性分配,这样自动工具关于那些一次性分配的额外抱怨就不会让你更难看到它关于你真正关心并想要追踪和修复的泄漏的抱怨。

另一方面,在一个执行一项任务(尽管可能是漫长而复杂的任务)然后退出的程序中,该程序在执行该任务的过程中分配了大量动态内存,并且在任务处理过程中大部分内存是必需的,试图显式地释放所有这些内存将是浪费时间,实际上(从编程时间、代码大小、运行时间和可靠性的角度来看)不尝试这样做可能是明智的。