Cleanup when user forces my program to exit?

筅森魡賤 提交于 2021-01-29 03:31:41

问题


In my C program, I have many data structures that are dynamically allocating memory. If the user does any of the following:

  • Alt-F4

  • Clicks on the X

  • Force quits via Task Manager, etc

then my program will have a memory leak. How do I do a set on close request feature so I can clean up my global variables before my program is shut down unnaturally?


回答1:


(Your terminology strongly suggests a Windows-specific application so I have written this answer accordingly. On other modern operating systems, the terminology is different, but the behavior is the same, except for some embedded environments, but if you were coding for those you would not have asked this question.)

First, the OS will automatically deallocate all memory associated with your process when it is terminated. You never have to worry about RAM remaining allocated.1

Second, you can get notified upon Alt-F4 / window close. I don't know the details, never having written a GUI application for Windows, but there should be some way you can arrange to get it treated the same as selecting Quit from the application's menus; your "toolkit" might even do this for you by default. The proper use of this notification is to save files to disk and cleanly shut down network dialogues. (The OS will also automatically close all file handles and disconnect all network sockets, but it won't flush unsaved changes for you, nor will it send application-layer goodbye messages.)

Third, you cannot receive a notification upon "force quit", and this is by design, because it's the software equivalent of the big red emergency stop button on an industrial robot -- it's for situations where making the process go away right now, no matter what is more important than any potential data loss. As you can't do anything about this, you should not worry about it.


1 As discussed in the comments: yes, this means it is not necessary to deallocate memory manually before exiting. In fact, it is more efficient if you don't, as discussed 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.

That said, there are some good reasons to deallocate memory manually before exiting. The most obvious is that some leak-detection tools need you to do it, because they do not know the difference between "memory that the application could have freed if it had bothered" and "memory that the application has lost all valid pointers to, and cannot free anymore". A less obvious case is if you are writing a library, or there's a possibility that your application might get turned into a library in the future. Libraries need to be able to manually free all of their allocations upon request by the application, because the application might need to set up, use, and tear down the library many times in the lifetime of one process. (However, it will be more efficient if the application sets up the library once in its lifetime, uses it repeatedly, and then doesn't bother tearing it down before exiting.)




回答2:


You can register a function to be called at exit, with atexit. This should handle normal termination (by returning from main or a call to exit anywhere in the program) and Alt+f4 and clicking the X too. However, there is nothing your program can do when it is killed (force quit in the task manager). Fortunately, most modern operating systems can and do clean up the memory used by your program, even when it dies of non-natural causes.

Here is an example of a program using atexit. The program creates (or truncates) a file called atexit.txt. When the program is terminated normally it writes Exited! to that file and closes the handle.

#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;
}

On Windows 8.1, compiled with MinGW/GCC it works for normal return and exit and when I click the X on the console window.



来源:https://stackoverflow.com/questions/39398796/cleanup-when-user-forces-my-program-to-exit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!