当一个程序终止时,使用malloc分配但未被释放的内存会发生什么?

16

假设我有以下程序

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    int * i;

    if ((i = malloc(sizeof(int) * 100)) == NULL) {
        printf("EROOR: unable to allocate memory \n");
        return -1;
    }

    /* memory is allocated successfully */

    /* memory is not free'ed but program terminates */
    // free(i);

    return 0;
}

以上程序调用malloc来分配一些内存,但没有调用free来释放它。程序在未释放内存的情况下终止。

Valgrind 明显检测到了内存泄漏。

<snap>
==14209== HEAP SUMMARY:
==14209==     in use at exit: 400 bytes in 1 blocks
==14209==   total heap usage: 1 allocs, 0 frees, 400 bytes allocated
==14209== 
<sanp>
==14209== LEAK SUMMARY:
==14209==    definitely lost: 400 bytes in 1 blocks
==14209==    indirectly lost: 0 bytes in 0 blocks
==14209==      possibly lost: 0 bytes in 0 blocks
==14209==    still reachable: 0 bytes in 0 blocks
==14209==         suppressed: 0 bytes in 0 blocks
==14209== 
==14209== For counts of detected and suppressed errors, rerun with: -v
==14209== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

问题:

程序终止时,分配但未被free的内存会发生什么?

更新: 考虑此代码在不同的操作系统上执行-比如Windows,Linux,Solaris,macOS等。在终止时,此代码的行为是否有所不同?


3
在大多数现代操作系统中,所有程序资源都会被释放或关闭。 - Some programmer dude
我可以问一下是什么引发了这个问题吗?与其担心如果不释放会发生什么,为什么不直接释放呢?然后你就可以停止担心了;valgrind 已经发生了,大家都很开心。问题解决了。 - Mr Lister
当你在使用malloc分配内存时,如果没有使用free释放这些内存,会发生什么? - alexis
@MrLister 我们不是有意跳过 free 函数的。通常情况下,我们需要处理非常庞大的代码库,其中 malloc 函数由一个模块完成,而 free 函数则由另一个模块完成等等。这些程序可以在 Windows、Solaris、Linux 和 Mac OS 等多种操作系统上运行。因此,我很好奇未释放内存的情况是如何处理的。 - Sangeeth Saravanaraj
@huelbois 对,尝试一些不应该做的事情可以让你学到很多。只要你永远不要在生产中使用这些东西! - Mr Lister
显示剩余2条评论
5个回答

14
其他回答已经告诉你两个重要的事情:
  1. 是的,内存会被操作系统释放,因此你在技术上不需要free()它。
  2. 无论如何都要释放malloc分配的所有内存是一个好的习惯。
然而,重要的是要说清楚为什么有良好的习惯去free()你所申请过的内存。我的看法如下:
  1. 习惯:如果你养成了每次使用malloc后都释放的习惯,那么当一个内存段不再存在于程序的生命周期中时,你就不会意外地忘记释放。
  2. 可维护性:如果有人来修改你的程序,使得一个内存段不再存在于程序的生命周期中,原始代码中的清理代码意味着新版本也很可能包含了清理代码。对我而言,这是最重要的原因。
  3. 调试:如果我们期望所有内存都被正确清理,那么发现实际上出现泄漏的内存就更容易了。

7
操作系统会回收未被释放的内存。
但是最好的做法是释放由malloc分配的所有内存。

这是一个有争议的问题:https://dev59.com/zVjUa4cB1Zd3GeqPPTzd#6347182;在生产环境中禁用程序终止前的显式释放内存可能是个好主意... - Christoph

4

一旦您的程序退出,操作系统就会回收内存。

操作系统不知道您的程序是否泄漏了内存,它只是为程序分配内存以便运行,一旦程序退出,操作系统就会回收该内存。

然而,其他资源(如文件描述符)可能被操作系统回收/未被回收,从而导致资源泄漏。

因此,一个好的实践是在退出前清理程序使用的所有资源。


1
当进程动态分配内存时,它从操作系统中借用一块或多块内存。如果进程不需要已经分配的内存,则释放该内存。然后,操作系统将这些块添加到其空闲列表中。当进程终止时,同样的情况也会发生。操作系统会回收进程使用的所有块。

阅读有关内存管理的更多信息。


0
更重要的是,FREE 确保您分配的内存/缓冲区的健全性,因此成为控制/捕获堆栈破坏的良好检查点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接