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

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

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

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


当前回答

即使您确定“已知的”内存泄漏不会造成严重破坏,也不要这样做。在最好的情况下,它会为你在不同的时间和地点犯下类似的、可能更严重的错误铺平道路。

对我来说,问这个问题就像问“我可以在凌晨3点没有人的时候闯红灯吗?”当然,在那个时候它可能不会造成任何麻烦,但它将为你在高峰时间做同样的事情提供一个杠杆!

其他回答

我完全同意JohnMcG的观点,只是想补充一点,我自己也有问题,无法及时发现真实的、潜在的严重内存泄漏,只是因为人们已经接受了良性的内存泄漏。随着时间的推移,这些病毒变得如此之多,在大量的良性病毒中发现严重病毒就变得越来越困难。

因此,至少为了你的程序员同事(也是为了你自己的未来),请尽快消除它们。

首先,让我们把定义更正一下。内存泄漏是指动态分配内存,例如使用malloc(),并且所有对内存的引用都在没有相应的free的情况下丢失。制作一个简单的方法是这样的:

#define BLK ((size_t)1024)
while(1){
    void * vp = malloc(BLK);
}

注意,每次在while(1)循环中,分配1024(+开销)字节,并将新地址分配给vp;没有指向之前malloc 'Ed块的剩余指针。这个程序保证运行到堆用完为止,并且没有办法恢复任何malloc'ed内存。内存从堆中“泄漏”出来,再也看不见了。

你所描述的,听起来就像

int main(){
    void * vp = malloc(LOTS);
    // Go do something useful
    return 0;
}

你分配内存,使用它直到程序结束。这不是内存泄漏;它不会损害程序,并且当程序终止时,所有的内存将被自动清除。

一般来说,应该避免内存泄漏。首先,因为就像你头顶上的高度和飞机库里的燃料一样,已经泄漏且无法恢复的内存是无用的;其次,在一开始就正确编码,不泄漏内存,比后来发现内存泄漏要容易得多。

在程序的最后一行省略释放内存是完全可以接受的,因为释放它不会对任何事情产生影响,因为程序再也不需要内存了。

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

如果你在程序开始时分配了一堆内存,但退出时没有释放它,这本身并不是内存泄漏。内存泄漏是指当程序循环遍历一段代码时,该代码分配堆,然后在没有释放它的情况下“失去跟踪”。

事实上,在退出之前不需要调用free()或delete。当进程退出时,它的所有内存都被操作系统回收(POSIX当然就是这种情况。在其他操作系统上-特别是嵌入式的- YMMV)。

对于退出时不释放内存,我唯一要注意的是,如果你重构了你的程序,例如,它变成了一个等待输入的服务,做你的程序所做的任何事情,然后循环等待另一个服务调用,那么你所编写的代码可能会变成内存泄漏。