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

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

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

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


当前回答

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

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.

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

其他回答

首先,让我们把定义更正一下。内存泄漏是指动态分配内存,例如使用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;
}

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

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

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

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

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

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

考虑这样一种情况,该应用程序后来从另一个应用程序中使用,可以在单独的窗口中打开其中的几个应用程序,也可以依次打开其中的几个应用程序来执行某些操作。如果它不是作为一个进程运行,而是作为一个库运行,那么调用程序会泄漏内存,因为您以为您冷跳过了内存清理。

使用一些智能指针,自动为你做(例如scoped_ptr从Boost库)

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