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、solarix、macos 等。这段代码在终止期间的行为有什么不同吗?

4

5 回答 5

14

其他答案告诉你两个重要的事情:

  1. 是的,内存是由操作系统回收的,所以你在技术上不需要free()它。
  2. 无论如何,释放您分配的所有内容都是一个好习惯。

但是,重要的是要说明为什么free()它对您分配的所有内容都是很好的做法。在我看来:

  1. 习惯:如果您养成了在 malloced 时释放的习惯,您就不会意外忘记在程序的生命周期内内存段何时不存在。
  2. 可维护性: 如果有人来重构您的程序,以便在程序的整个生命周期内不再存在一段内存,则原始版本中存在清理代码将意味着重构版本很可能还包含清理代码. 对我来说,这是最重要的原因。
  3. 调试:如果我们期望所有内存都被正确清理,那么发现实际泄漏的内存要容易得多。
于 2012-04-19T07:55:31.450 回答
7

操作系统将回收未释放的内存。

但是释放所有分配的内存是一个好习惯malloc

于 2012-04-19T07:46:32.373 回答
4

程序退出后,操作系统会回收内存。
操作系统不了解您的程序泄漏了内存,它只是将内存分配给程序以供运行,一旦程序退出,它就会回收该内存。

但是,操作系统可能/可能不会重新校准文件描述符等其他资源,从而导致资源泄漏。

因此,一个程序应该在退出之前清理它使用的所有资源是一个很好的做法。

于 2012-04-19T07:45:17.170 回答
1

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

阅读内存管理了解更多信息。

于 2012-04-19T07:51:40.680 回答
0

更重要的是,FREE 确保了您分配的内存/缓冲区的健全性,因此存在一个很好的检查点来遏制/追赶堆损坏。

于 2014-01-17T05:46:14.653 回答