如果程序即将退出,释放分配的内存真的很重要吗?

fla*_*006 2 c free pointers memory-leaks memory-management

据我所知,如果你正在分配内存以临时存储某些内容,比如响应用户操作,并且当代码再次到达那一点时你就不再需要内存了,你应该释放内存以便它不会不会造成泄漏.如果不清楚,这里有一个例子,我知道释放内存很重要:

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

void countToNumber(int n)
{
    int *numbers = malloc(sizeof(int) * n);

    int i;
    for (i=0; i<n; i++) {
        numbers[i] = i+1;
    }
    for (i=0; i<n; i++) {
        // Yes, simply using "i+1" instead of "numbers[i]" in the printf would make the array unnecessary.
        // But the point of the example is using malloc/free, so pretend it makes sense to use one here.
        printf("%d ", numbers[i]);
    }
    putchar('\n');

    free(numbers); // Freeing is absolutely necessary here; this function could be called any number of times.
}

int main(int argc, char *argv[])
{
    puts("Enter a number to count to that number.");
    puts("Entering zero or a negative number will quit the program.");

    int n;
    while (scanf("%d", &n), n > 0) {
        countToNumber(n);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,有时我会在程序运行的整个过程中需要该内存,即使我最终为同一目的分配更多内存,仍然会使用存储在先前分配的内存中的数据.因此,我最终需要释放内存的唯一时间就在程序退出之前.

但如果我最终没有释放内存,那真的会导致内存泄漏吗?我认为操作系统会在进程退出后立即回收内存.即使它不会导致内存泄漏,还有另一个原因是释放内存很重要,前提是这不是C++并且没有需要调用的析构函数吗?

例如,free以下示例中是否需要呼叫?

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

int main(int argc, char *argv[])
{
    void *ptr = malloc(1024);
    // do something with ptr
    free(ptr);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这free并不是很不方便,但是在我为包含指向其他动态分配数据的指针的结构动态分配内存的情况下,我很高兴知道我不需要设置循环来做它.特别是如果struct中的指针是一个具有相同结构的对象,我需要以递归方式删除它们.

mti*_*nic 5

一般情况下,操作系统将回收内存,所以没有,你不要free()它.但这样做真的很好,在某些情况下,它实际上可能有所作为.几个例子:

  • 您将程序作为另一个进程的子进程执行.根据完成的方式(参见下面的注释),在父完成之前不会释放内存.如果父母永远不会完成,那就是永久性的泄漏.
  • 您将程序更改为执行其他操作.现在你需要追捕每条出口路径并释放所有东西,你可能会忘记一些.
  • 回收记忆是OS的意志.所有主要的都做到了,但如果你将程序移植到另一个系统,它可能不会.
  • 静态分析和调试工具可以更好地使用正确的代码.
  • 如果内存在进程之间共享,则只能在所有进程终止后释放,或者甚至可能不会.

顺便说一句,这只是关于记忆.释放其他资源(例如关闭文件(fclose()))更为重要,因为某些操作系统(Windows)无法正确刷新流.

  • @mitjanic:nops,(C99,7.19.3p5)"如果main函数返回到其原始调用者,或者调用了exit函数,则在程序终止之前关闭所有打开的文件(因此刷新所有输出流)." (3认同)
  • @AlterMann嗯,我会......我仍然坚持原来的观点,因为至少Windows/MSVC不符合标准,这是一个非常重要的平台.不过,你完全正确.谢谢! (2认同)