在C或c++应用程序中出现内存泄漏是可以接受的吗?

如果分配一些内存并一直使用到应用程序中的最后一行代码(例如,全局对象的析构函数),会怎样?只要内存消耗不随时间增长,那么当应用程序终止时(在Windows、Mac和Linux上),是否可以信任操作系统为您释放内存?如果内存一直被使用,直到被操作系统释放,您会认为这是真正的内存泄漏吗?

如果是第三方库将这种情况强加给您,该怎么办?会拒绝使用第三方库,不管它有多好?

我只看到了一个实际的缺点,那就是这些良性泄漏将在内存泄漏检测工具中显示为误报。


当前回答

只要您的内存利用率不随着时间的推移而增加,这取决于情况。如果你在服务器软件中做很多复杂的同步,比如启动阻塞系统调用的后台线程,那么完全关闭可能太复杂了。在这种情况下,备选方案可能是:

直到进程退出才清理内存的库。 您编写了额外的500行代码,并向类中添加了另一个互斥量和条件变量,以便它可以从测试中干净地关闭—但是这些代码从未在生产中使用,在生产中服务器只会因崩溃而终止。

其他回答

No.

作为专业人士,我们不应该问自己“这样做是否合适?”,而应该问自己“这样做是否有一个好的理由?”“寻找内存泄漏是一种痛苦”并不是一个好的理由。

我喜欢把事情简单化。简单的规则是,我的程序应该没有内存泄漏。

这也让我的生活变得简单。如果我检测到内存泄漏,我会消除它,而不是通过一些复杂的决策树结构来确定它是否是“可接受的”内存泄漏。

它类似于编译器警告——警告对我的特定应用程序是致命的吗?也许不是。

但归根结底,这是一个职业纪律问题。容忍编译器警告和容忍内存泄漏是一个坏习惯,最终会给我带来麻烦。

举个极端的例子,外科医生把手术设备留在病人体内是可以接受的吗?

尽管移除设备的成本/风险可能会超过保留设备的成本/风险,并且可能在某些情况下它是无害的,但如果我在外科医生网站上看到这个问题,看到除了“不”之外的任何答案,这将严重削弱我对医疗行业的信心。

如果是第三方图书馆把这种情况强加给我,我会严重怀疑该图书馆的整体质量。这就像我试驾一辆车,发现其中一个杯托里有几个松动的垫圈和螺母——这本身可能不是什么大问题,但这表明我缺乏对质量的承诺,所以我会考虑其他选择。

我同意vfilby -这要看情况。在Windows中,我们将内存泄漏视为相对严重的错误。但是,这很大程度上取决于分量。

例如,对于很少运行且运行时间有限的组件,内存泄漏不是很严重。这些组件运行,完成工作,然后退出。当它们退出时,所有内存都被隐式释放。

但是,服务或其他长期运行组件(如shell)中的内存泄漏非常严重。原因是这些bug会随着时间的推移“窃取”内存。恢复的唯一方法是重新启动组件。大多数人不知道如何重新启动服务或shell——所以如果他们的系统性能受到影响,他们就重新启动。

所以,如果你有一个泄漏-评估它的影响两种方式

你的软件和你的用户体验。 对于系统(和用户)来说,节省系统资源是非常重要的。 修复对维护和可靠性的影响。 在其他地方造成倒退的可能性。

前甲板

如果分配内存并一直使用到程序的最后一行,这就不是泄漏。如果您分配内存并忘记它,即使内存数量没有增长,这也是一个问题。已分配但未使用的内存可能导致其他程序运行速度变慢或根本不运行。

我相信答案是否定的,永远不要允许内存泄漏,我有一些我没有看到明确说明的原因。这里有很好的技术答案,但我认为真正的答案取决于更多的社会/人类原因。

(首先,请注意,正如其他人所提到的,真正的泄漏是当您的程序在任何时候失去对已分配内存资源的跟踪时。在C语言中,当你malloc()指向一个指针并让该指针离开作用域而没有先执行free()时,就会发生这种情况。

你做决定的关键在于习惯。当你用一种使用指针的语言编写代码时,你会经常使用指针。指针是危险的;它们是向代码中添加各种严重问题的最简单方法。

当你在编程的时候,有时你会很专注,有时你会很累、生气或担心。在那些有点分心的时间里,你会更多地自动编码。自动驾驶效果不会区分一次性代码和大型项目中的模块。在此期间,您所建立的习惯将最终出现在您的代码库中。

所以,不,永远不要允许内存泄漏,就像你在换车道时仍然应该检查盲点一样,即使你是路上唯一的车。当你活跃的大脑分心时,好习惯可以让你避免灾难性的失误。

除了“习惯”问题之外,指针是复杂的,通常需要大量的脑力来在精神上跟踪。当涉及到指针的使用时,最好不要“搅浑水”,特别是当您是编程新手时。

还有更多的社交方面。通过正确使用malloc()和free(),任何查看您的代码的人都会感到轻松;你在管理你的资源。然而,如果你不这样做,他们马上就会怀疑有问题。

也许您已经发现内存泄漏在这种情况下不会造成任何损害,但是代码的每个维护者在阅读这段代码时也必须在自己的头脑中解决这个问题。通过使用free(),您甚至不需要考虑这个问题。

最后,编程是用一种明确的语言编写一个过程的心理模型,这样人和计算机就可以完全理解所述过程。好的编程实践的一个重要部分是永远不要引入不必要的歧义。

智能编程是灵活和通用的。糟糕的编程是模棱两可的。

Some great answers here. To add another perspective to this question, I'll address a case where memory leak is not only acceptable but desirable: in Windows drivers environment the developer provides a set of callbacks that are being run by the OS whenever required. One of the callbacks is a 'Shutdown' callback, which runs prior to system being shut off/restarted. Unlike standard situations, not only memory release is not necessary (system will be off in a moment), it's even discouraged - to make the shutdown as fast as possible and prevent the overhead of memory management.