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

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

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

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


当前回答

我看到了和所有场景问题一样的问题,比如:当程序改变时,会发生什么?突然,这个小内存泄漏被调用了1000万次,而程序的结尾在不同的地方,所以它很重要?如果它在库中,那么请向库维护者记录错误,不要在您自己的代码中泄漏。

其他回答

一般情况下,如果遇到无法避免的内存泄漏,则需要更加认真地考虑对象所有权问题。

但对于你的问题,我的回答是在产品代码中,是的。在开发过程中,没有。这听起来可能有些倒退,但我的理由是:

In the situation you describe, where the memory is held until the end of the program, it's perfectly okay to not release it. Once your process exits, the OS will clean up anyway. In fact, it might make the user's experience better: In a game I've worked on, the programmers thought it would be cleaner to free all the memory before exiting, causing the shutdown of the program to take up to half a minute! A quick change that just called exit() instead made the process disappear immediately, and put the user back to the desktop where he wanted to be.

但是,您对调试工具的看法是正确的:它们会突然发作,而且所有的假阳性可能会使查找真正的内存泄漏变得很痛苦。正因为如此,总是编写释放内存的调试代码,并在发布时禁用它。

虽然大多数答案都集中在真正的内存泄漏(这是不正确的,因为它们是草率编码的标志),但这个问题的这一部分对我来说似乎更有趣:

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

如果使用了相关的内存,则在程序结束之前不能释放它。释放是由程序退出还是由操作系统完成并不重要。只要有文档记录,这样更改就不会引入真正的内存泄漏,并且在图中不涉及c++析构函数或C清理函数。未关闭的文件可能通过泄漏的file对象显示,但缺少fclose()也可能导致缓冲区不被刷新。

所以,回到最初的情况,在我看来,它本身是完全OK的,以至于Valgrind,最强大的泄漏探测器之一,只会在要求时处理此类泄漏。在Valgrind上,当您覆盖一个指针而没有事先释放它时,它会被认为是内存泄漏,因为它更有可能再次发生,并导致堆无休止地增长。

然后,就没有仍然可以访问的nfreed内存块了。我们可以确保在出口释放所有人,但这本身就是浪费时间。关键是他们之前能不能被释放。降低内存消耗在任何情况下都是有用的。

我看到了和所有场景问题一样的问题,比如:当程序改变时,会发生什么?突然,这个小内存泄漏被调用了1000万次,而程序的结尾在不同的地方,所以它很重要?如果它在库中,那么请向库维护者记录错误,不要在您自己的代码中泄漏。

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

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

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

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

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

在应用程序运行后清理操作系统在概念上没有问题。

这实际上取决于应用程序以及它将如何运行。在需要运行数周的应用程序中不断发生的泄漏必须得到处理,但是一个不需要太多内存就能计算结果的小工具应该不是问题。

许多脚本语言不垃圾收集循环引用是有原因的……对于它们的使用模式,这不是一个实际的问题,因此浪费的资源和浪费的内存一样多。