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

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

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

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


当前回答

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

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

退出应用程序的好处是:

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

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

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

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

其他回答

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

If I understood correctly, you don't explicitly free memory (which can be freed because you still have a pointer) and rely on OS to free it during process termination. Though this may seem okay for simple program, consider the situation where your code is moved into a library and becomes a part of some resident daemon process running 24/7. Say this daemon spawns a thread each time it needs to do something useful using your code and say it spawns thousands of threads every hour. In this case you will get real memory leak.

不幸的是,这种情况在现实生活中并非不可能,一致的内存管理技术可能会使您的生活更轻松。

从历史上看,在某些边缘情况下,它在某些操作系统上确实很重要。这些边缘情况在未来可能会存在。

Here's an example, on SunOS in the Sun 3 era, there was an issue if a process used exec (or more traditionally fork and then exec), the subsequent new process would inherit the same memory footprint as the parent and it could not be shrunk. If a parent process allocated 1/2 gig of memory and didn't free it before calling exec, the child process would start using that same 1/2 gig (even though it wasn't allocated). This behavior was best exhibited by SunTools (their default windowing system), which was a memory hog. Every app that it spawned was created via fork/exec and inherited SunTools footprint, quickly filling up swap space.

也许是在细枝末节:如果您的应用程序运行在UNIX上,可能会变成僵尸怎么办?在这种情况下,内存不会被操作系统回收。所以我说你应该在程序退出之前重新分配内存。

这个问题已经讨论得令人作呕了。最重要的是,内存泄漏是一个bug,必须修复。如果第三方库泄露了内存,就会让人怀疑它还有什么问题,不是吗?如果你要造一辆汽车,你会使用一个偶尔漏油的发动机吗?毕竟,引擎是别人做的,所以这不是你的错,你不能修,对吧?

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

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

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的。