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

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

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

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


当前回答

I'm going to give the unpopular but practical answer that it's always wrong to free memory unless doing so will reduce the memory usage of your program. For instance a program that makes a single allocation or series of allocations to load the dataset it will use for its entire lifetime has no need to free anything. In the more common case of a large program with very dynamic memory requirements (think of a web browser), you should obviously free memory you're no longer using as soon as you can (for instance closing a tab/document/etc.), but there's no reason to free anything when the user selects clicks "exit", and doing so is actually harmful to the user experience.

为什么?释放内存需要接触内存。即使您的系统的malloc实现碰巧没有在分配的内存块附近存储元数据,您也可能会遍历递归结构,只是为了找到所有需要释放的指针。

Now, suppose your program has worked with a large volume of data, but hasn't touched most of it for a while (again, web browser is a great example). If the user is running a lot of apps, a good portion of that data has likely been swapped to disk. If you just exit(0) or return from main, it exits instantly. Great user experience. If you go to the trouble of trying to free everything, you may spend 5 seconds or more swapping all the data back in, only to throw it away immediately after that. Waste of user's time. Waste of laptop's battery life. Waste of wear on the hard disk.

这不仅仅是理论上的。每当我发现自己加载了太多的应用程序,磁盘开始抖动时,我甚至不会考虑点击“退出”。我以最快的速度到达一个终端,输入killall -9…因为我知道"退出"只会让情况更糟。

其他回答

规则很简单:如果你用完了一些内存,就清理它。 有时,即使我们稍后需要一些实例,但我们注意到我们会大量使用内存,所以它会影响性能,因为交换到磁盘,我们可以将数据存储到磁盘文件中,然后重新加载它们,有时这种技术会优化你的程序。

不,你不应该有漏洞,操作系统会为你清理。原因(据我所知,在上面的答案中没有提到)是你永远不知道什么时候你的main()会在另一个程序中作为函数/模块被重用。如果你的main()在其他人的软件中经常被调用,那么这个软件就会有内存泄漏,随着时间的推移会消耗内存。

KIV

在以前,我可能会说是的,在你的程序中让一些内存泄漏有时是可以接受的(它仍然是快速原型),但现在有了5到6次的经验,即使是跟踪最小的泄漏也会发现一些真正严重的功能错误。在数据实体的生命周期还不清楚的情况下,让程序发生泄漏,显示出严重缺乏分析。总之,了解程序中发生了什么总是一个好主意。

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

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

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.

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

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

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

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

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

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