如果程序即将退出,释放分配的内存真的很重要吗?
Is it really important to free allocated memory if the program's just about to exit?
我知道如果你正在分配内存来临时存储一些东西,比如响应用户操作,当代码再次到达那个点时你不再需要内存了,你应该释放内存,所以它不会导致泄漏。如果不清楚,下面是我知道释放内存很重要的示例:
#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;
}
然而,有时,我会在整个程序 运行 期间都需要该内存,即使我最终为同一目的分配更多内存,存储在先前分配的内存中的数据仍在使用。所以我最终需要释放内存的唯一时间是在程序退出之前。
但是如果我最终不释放内存,那真的会导致内存泄漏吗?我认为操作系统会在进程退出后立即回收内存。即使它不会导致内存泄漏,如果这不是 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;
}
在那种情况下 free
并不是很不方便,但是在我为包含指向 other 动态分配的指针的结构动态分配内存的情况下数据,很高兴知道我不需要设置循环来完成它。特别是如果结构中的指针指向具有相同结构的对象,我需要递归删除它们。
一般来说,OS 会回收内存,所以不,你 没有 到 free()
它。但这样做确实是一种很好的做法,在某些情况下,它实际上可能会有所作为。几个例子:
- 您将程序作为另一个进程的子进程来执行。根据完成方式(参见下面的注释),在父级完成之前不会释放内存。如果父级永远不会完成,那就是永久性泄漏。
- 您更改程序以执行其他操作。现在你需要寻找每条出口路径并释放所有东西,你可能会忘记一些。
- 回收内存是 OS 自愿的。所有主要的都这样做,但是如果你把你的程序移植到另一个系统上,它可能不会。
- 静态分析和调试工具使用正确的代码效果更好。
- 如果内存在进程之间共享,它可能只有在所有进程终止后才被释放,甚至可能不会。
顺便说一下,这只是关于内存的。释放其他资源,例如关闭文件 (fclose()
) 更为重要,因为一些 OSes (Windows) 没有正确刷新流。
我知道如果你正在分配内存来临时存储一些东西,比如响应用户操作,当代码再次到达那个点时你不再需要内存了,你应该释放内存,所以它不会导致泄漏。如果不清楚,下面是我知道释放内存很重要的示例:
#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;
}
然而,有时,我会在整个程序 运行 期间都需要该内存,即使我最终为同一目的分配更多内存,存储在先前分配的内存中的数据仍在使用。所以我最终需要释放内存的唯一时间是在程序退出之前。
但是如果我最终不释放内存,那真的会导致内存泄漏吗?我认为操作系统会在进程退出后立即回收内存。即使它不会导致内存泄漏,如果这不是 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;
}
在那种情况下 free
并不是很不方便,但是在我为包含指向 other 动态分配的指针的结构动态分配内存的情况下数据,很高兴知道我不需要设置循环来完成它。特别是如果结构中的指针指向具有相同结构的对象,我需要递归删除它们。
一般来说,OS 会回收内存,所以不,你 没有 到 free()
它。但这样做确实是一种很好的做法,在某些情况下,它实际上可能会有所作为。几个例子:
- 您将程序作为另一个进程的子进程来执行。根据完成方式(参见下面的注释),在父级完成之前不会释放内存。如果父级永远不会完成,那就是永久性泄漏。
- 您更改程序以执行其他操作。现在你需要寻找每条出口路径并释放所有东西,你可能会忘记一些。
- 回收内存是 OS 自愿的。所有主要的都这样做,但是如果你把你的程序移植到另一个系统上,它可能不会。
- 静态分析和调试工具使用正确的代码效果更好。
- 如果内存在进程之间共享,它可能只有在所有进程终止后才被释放,甚至可能不会。
顺便说一下,这只是关于内存的。释放其他资源,例如关闭文件 (fclose()
) 更为重要,因为一些 OSes (Windows) 没有正确刷新流。