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

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

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

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


当前回答

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

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

其他回答

我在高中上过一门C课,老师说当你malloc的时候一定要确保自由。

但是当我在大学里上另一门课的时候,教授说对那些只运行一秒钟的小程序不免费是可以的。 因此,我认为这不会损害您的程序,但免费提供强大、健康的代码是一种很好的实践。

当应用程序关闭时,可以认为最好不要释放内存。

理论上,操作系统应该释放应用程序使用的资源,但总有一些资源是这个规则的例外。所以要小心。

退出应用程序的好处是:

操作系统只释放一个块,而不是很多很多小块。这意味着关机速度要快得多。尤其是在内存管理缓慢的Windows上。

只是退出的坏处其实有两点

很容易忘记释放操作系统没有跟踪的资源,或者操作系统可能会等待一段时间才释放。一个例子是TCP套接字。 内存跟踪软件将报告在退出时未释放的所有内容为泄漏。

因此,您可能希望有两种关机模式,一种是针对最终用户的快速且不友好的关机模式,另一种是针对开发人员的缓慢且彻底的关机模式。只是要确保两者都测试:)

我很惊讶看到这么多关于内存泄漏的错误定义。如果没有一个具体的定义,关于它是否是坏事的讨论就不会有任何结果。

正如一些评论员正确地指出的那样,只有当进程分配的内存超出作用域,以至于该进程不再能够引用或删除它时,才会发生内存泄漏。

A process which is grabbing more and more memory is not necessarily leaking. So long as it is able to reference and deallocate that memory, then it remains under the explicit control of the process and has not leaked. The process may well be badly designed, especially in the context of a system where memory is limited, but this is not the same as a leak. Conversely, losing scope of, say, a 32 byte buffer is still a leak, even though the amount of memory leaked is small. If you think this is insignificant, wait until someone wraps an algorithm around your library call and calls it 10,000 times.

我认为没有任何理由允许在您自己的代码中泄漏,无论多么小。现代编程语言,如C和c++,不遗余力地帮助程序员防止此类泄漏,并且很少有好的理由不采用好的编程技术——特别是在与特定的语言功能相结合时——来防止泄漏。

对于现有的或第三方代码,您对质量的控制或进行更改的能力可能非常有限,这取决于泄漏的严重程度,您可能被迫接受或采取缓解措施,例如定期重新启动进程以减少泄漏的影响。

更改或替换现有的(泄漏的)代码可能是不可能的,因此您可能不得不接受它。然而,这并不等同于宣称它是OK的。

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

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

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

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

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

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

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

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

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

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

理论上没有,实际情况要视情况而定。

这实际上取决于程序处理了多少数据,程序运行的频率以及它是否持续运行。

如果我有一个快速程序,读取少量数据进行计算并退出,那么就永远不会注意到一个小的内存泄漏。因为程序不会运行很长时间,并且只使用少量的内存,所以当程序存在时,泄漏将很小并被释放。

另一方面,如果我有一个处理数百万条记录并运行很长时间的程序,一个小的内存泄漏可能会在足够的时间内使机器停机。

对于有泄漏的第三方库,如果它们导致问题,要么修复库,要么找到更好的替代方案。如果不造成问题,这真的重要吗?