Windows和Linux。
当我在我的C程序中分配内存时,良好的编码要求我在程序结束前释放内存。
假设如下:
int main (int argc, char *argv[]) {
char *f_name;
FILE *i_file;
f_name = malloc(some_amount);
// put something in f_name */
i_file = fopen(f_name, "r");
if (i_file == NULL) {
perror("Error opening file.");
exit(EXIT_FAILURE);
}
free(f_name);
return EXIT_SUCCESS;
}
如果程序在我调用" free"之前终止,操作系统会在程序退出时恢复任何未释放的内存吗?或者我是否会从系统重启之前蚕食我的3Gb左右可用内存?
谢谢,Mark。
答案 0 :(得分:1)
您不必担心Windows和Linux等流行的操作系统。
当进程终止时,虚拟内存不再存在。因此,在进程终止后,它不可能泄漏。
物理内存始终属于要分配的操作系统,无论您的进程是否仍在运行。 (除非你锁定你的分配,在这种情况下,当相应的虚拟内存映射被销毁时,无论如何都会在进程终止时停止锁定它。)
有一些资源没有被清理(比如某些类型的共享内存),但这很奇特。
当您调用malloc
时,通常只保留后备存储(本质上是RAM +交换)并创建虚拟内存映射(基本上是免费的)。当您第一次写入该虚拟内存映射时,内存(RAM)的物理页面会映射到它中以“后退”它。 RAM总是属于要使用的操作系统,如果它认为明智,操作系统会将RAM重新用于其他目的。
当进程终止时,其地址空间不再存在。这意味着任何虚拟内存映射或预留都会消失。当虚拟内存映射消失时,非共享物理页面的使用计数将降至零,从而使这些物理内存页面免费。
值得详细了解这一点,因为如果您不了解幕后发生的情况,您可以轻松得出有关边缘案例的错误结论。此外,这将为您提供一个框架,用于插入文件映射,内存过量使用和共享内存等概念。
答案 1 :(得分:0)
操作系统回收内存。
某些程序(如网络服务器)从不打算退出,只是继续运行并提供请求。他们在技术上分配的内存不需要返回。
答案 2 :(得分:0)
在您的示例中,使用此分支确实会导致内存泄漏:
f_name = malloc(some_amount);
// put something in f_name */
i_file = fopen(f_name, "r");
if (i_file == NULL) {
perror("Error opening file.");
exit(EXIT_FAILURE); // <--- f_name leaks here!
}
它只是一次性泄漏,在程序的整个生命周期中都不会经常发生,常见的操作系统会在终止时清理泄漏的内存。它不太可能成为影响系统性能的问题,但是它将成为Valgrind等仪器突出显示的诊断,因此对于调试来说,它是明智的。 <{1}}之前的free(f_name);
。
该终止不被视为异常,因为它是由exit(EXIT_FAILURE);
的呼叫引起的。尽管如此,调用exit
或发出信号引起的异常终止可能会在此泄漏的基础上复合。
当程序退出时OS会恢复任何未释放的内存吗?
在C标准中没有要求存在操作系统,更不用说恢复未释放的内存了。一些极简主义操作系统可能会在您之后不清理。同样,如果您的程序在脚本环境(即CGI)中运行,或者它被刻入芯片中(在这种情况下您可能不希望程序终止),那么您可能会在以后遇到问题。
答案 3 :(得分:-3)
实际上,当流程终止时,程序的内存分配会自动释放。但是,如果函数调用在该函数的代码块中的free()
或delete
调用之前收到异常,则除非被智能引用,否则不会释放内存指针或某种对象。分配内存自动释放的一个推荐选项是使用std::shared_ptr
,如下所示:
void BadFunction(){
char *someMemory = (char *)malloc(1024);
DoSomethingThatMakesAnException();
delete someMemory;// This never gets called!
}
void GoodFunction(){
std::shared_ptr<char> someMemory = std::shared_ptr<char>((char *)malloc(1024));
DoSomethingThatMakesAnException();
// someMemory is freed automatically, even on exception!
}