当用户强制我的程序退出时清理?
Cleanup when user forces my program to exit?
在我的 C 程序中,我有许多动态分配内存的数据结构。如果用户执行以下任一操作:
Alt-F4
点击 X
通过任务管理器等强制退出
那么我的程序就会发生内存泄漏。我如何执行 关闭请求设置 功能,以便我可以在我的程序异常关闭之前清理我的全局变量?
您可以使用 atexit
注册要在退出时调用的函数。这应该处理正常终止(通过从 main
返回或在程序中的任何地方调用 exit
)和 Alt+f4 并单击 X。但是,您的程序在被终止时无能为力(在任务管理器中强制退出)。幸运的是,大多数现代操作系统都可以而且确实会清理您的程序使用的内存,即使它因非自然原因而死。
这是一个使用 atexit
的程序示例。该程序创建(或截断)一个名为 atexit.txt
的文件。当程序正常终止时,它会将 Exited!
写入该文件并关闭句柄。
#include <stdlib.h>
#include <stdio.h>
FILE * quitFp;
void onExit(){
fputs("Exited!", quitFp);
fclose(quitFp);
}
int main(){
quitFp = fopen("atexit.txt", "w+");
if(!quitFp){
return 1;
}
atexit(onExit);
puts("Press enter to exit");
getchar();
return 0;
}
在 Windows 8.1 上,使用 MinGW/GCC 编译它适用于正常的 return
和 exit
,当我在控制台上单击 X 时 window。
(您的术语强烈建议使用 Windows 特定的应用程序,因此我相应地写了这个答案。在其他现代操作系统上,术语不同,但行为相同,除了某些嵌入式环境,但如果您是为那些人编写代码,您就不会问这个问题。)
首先,OS 将在终止时自动释放与您的进程关联的所有内存。您永远不必担心剩余分配的 RAM。1
其次,您可以 在 Alt-F4 / window 关闭时收到通知。我不知道细节,从来没有为 Windows 编写过 GUI 应用程序,但是应该有一些方法可以安排让它像从应用程序的菜单中选择退出一样对待;您的 "toolkit" 甚至可能默认为您执行此操作。正确使用此通知是将文件保存到磁盘并干净地关闭网络对话。 (OS 也会自动 close 所有文件句柄和 disconnect 所有网络套接字,但它不会为你刷新未保存的更改,也不会发送应用层再见消息。)
第三,您无法在"force quit"时收到通知,这是设计使然,因为它的软件相当于工业设备上的大红色紧急停止按钮robot -- 它适用于 立即停止进程的情况,无论什么 都比任何潜在的数据丢失更重要。由于您对此无能为力,因此您不必担心。
1 正如评论中所讨论的:是的,这意味着在退出之前没有必要手动释放内存。事实上,如果您不,它会更有效,如讨论here and here. The "common wisdom" that manual deallocation is required dates to the early days of microcomputers; (some iterations of) CP/M and MS-DOS did indeed need each application to deallocate memory manually; nowadays it is an instance of cargo-cult programming。
也就是说, 有一些很好的理由在退出前手动释放内存。最明显的是,某些泄漏检测工具需要您执行此操作,因为它们不知道 "memory that the application could have freed if it had bothered" 和 "memory that the application has lost all valid pointers to, and cannot free anymore" 之间的区别。一个不太明显的情况是,如果您正在编写一个库,或者您的应用程序将来可能会变成一个库。库需要能够根据应用程序的请求手动释放所有分配,因为应用程序可能需要在库的生命周期内多次设置、使用和拆除库一个过程。 (但是,如果 application 在其生命周期中设置一次库,重复使用它,然后在退出之前不费心拆除它,效率会更高。)
在我的 C 程序中,我有许多动态分配内存的数据结构。如果用户执行以下任一操作:
Alt-F4
点击 X
通过任务管理器等强制退出
那么我的程序就会发生内存泄漏。我如何执行 关闭请求设置 功能,以便我可以在我的程序异常关闭之前清理我的全局变量?
您可以使用 atexit
注册要在退出时调用的函数。这应该处理正常终止(通过从 main
返回或在程序中的任何地方调用 exit
)和 Alt+f4 并单击 X。但是,您的程序在被终止时无能为力(在任务管理器中强制退出)。幸运的是,大多数现代操作系统都可以而且确实会清理您的程序使用的内存,即使它因非自然原因而死。
这是一个使用 atexit
的程序示例。该程序创建(或截断)一个名为 atexit.txt
的文件。当程序正常终止时,它会将 Exited!
写入该文件并关闭句柄。
#include <stdlib.h>
#include <stdio.h>
FILE * quitFp;
void onExit(){
fputs("Exited!", quitFp);
fclose(quitFp);
}
int main(){
quitFp = fopen("atexit.txt", "w+");
if(!quitFp){
return 1;
}
atexit(onExit);
puts("Press enter to exit");
getchar();
return 0;
}
在 Windows 8.1 上,使用 MinGW/GCC 编译它适用于正常的 return
和 exit
,当我在控制台上单击 X 时 window。
(您的术语强烈建议使用 Windows 特定的应用程序,因此我相应地写了这个答案。在其他现代操作系统上,术语不同,但行为相同,除了某些嵌入式环境,但如果您是为那些人编写代码,您就不会问这个问题。)
首先,OS 将在终止时自动释放与您的进程关联的所有内存。您永远不必担心剩余分配的 RAM。1
其次,您可以 在 Alt-F4 / window 关闭时收到通知。我不知道细节,从来没有为 Windows 编写过 GUI 应用程序,但是应该有一些方法可以安排让它像从应用程序的菜单中选择退出一样对待;您的 "toolkit" 甚至可能默认为您执行此操作。正确使用此通知是将文件保存到磁盘并干净地关闭网络对话。 (OS 也会自动 close 所有文件句柄和 disconnect 所有网络套接字,但它不会为你刷新未保存的更改,也不会发送应用层再见消息。)
第三,您无法在"force quit"时收到通知,这是设计使然,因为它的软件相当于工业设备上的大红色紧急停止按钮robot -- 它适用于 立即停止进程的情况,无论什么 都比任何潜在的数据丢失更重要。由于您对此无能为力,因此您不必担心。
1 正如评论中所讨论的:是的,这意味着在退出之前没有必要手动释放内存。事实上,如果您不,它会更有效,如讨论here and here. The "common wisdom" that manual deallocation is required dates to the early days of microcomputers; (some iterations of) CP/M and MS-DOS did indeed need each application to deallocate memory manually; nowadays it is an instance of cargo-cult programming。
也就是说, 有一些很好的理由在退出前手动释放内存。最明显的是,某些泄漏检测工具需要您执行此操作,因为它们不知道 "memory that the application could have freed if it had bothered" 和 "memory that the application has lost all valid pointers to, and cannot free anymore" 之间的区别。一个不太明显的情况是,如果您正在编写一个库,或者您的应用程序将来可能会变成一个库。库需要能够根据应用程序的请求手动释放所有分配,因为应用程序可能需要在库的生命周期内多次设置、使用和拆除库一个过程。 (但是,如果 application 在其生命周期中设置一次库,重复使用它,然后在退出之前不费心拆除它,效率会更高。)