How to avoid memory leak when user press ctrl+c un

2019-02-03 22:32发布

In my program written with C and C++, I will new an object to fulfill the task, then delete the object.

At the moment after new object but before delete object, if the user presses ctrl+c to break the process, that will cause delete not to be called and a memory leak occurs.

What should I do to avoid this situation?

Also, if the memory was reclaimed by the OS, what about the opened files? Are they closed by the OS or should I close them manualy?

7条回答
该账号已被封号
2楼-- · 2019-02-03 22:49

The OS will reclaim the memory allocated by the process when the process exits as a result of Ctrl-C or any other means.

查看更多
劳资没心,怎么记你
3楼-- · 2019-02-03 22:51

If you allocated any SYSV Shared Memory Segments using shmget(2) then you must clean up after yourself with shmctl(2).

If you allocated any POSIX Shared Memory Segments using shm_open(3) then you must clean up after yourself with shm_unlink(3).

Both SYSV and POSIX shared memory segments persist past process termination. You can see what persists using the ipcs(1) tool.

Of course, if you haven't used any SYSV or POSIX shared memory segments, then this is all just noise. :)

查看更多
做个烂人
4楼-- · 2019-02-03 22:51

If the process quits, a memory leak will NOT normally occur.

Most of the memory you allocate will be freed on Ctrl+C. If you see memory usage not return to its prior level, it is almost certainly caused by buffered filesystem blocks.

However, you should definitely clean things up, in particular if you have used any other types of resources:

  • Files created in temporary directories won't be deleted. This includes /dev/shm, leaving such a file could be considered a "memory leak".
  • System V or posix shared memory segments won't get thrown away when your process quits. If this bothers you, clean them up specifically. Alternatively, clean them up on a subsequent run.

Normally a leak (of a persistent or semi-persistent object e.g. file) doesn't matter if a subsequent run doesn't leak more memory. So cleaning up on a future run is good enough.

Imagine a process running every 5 minutes from "cron", if it crashes on each run and leaves some mess, it's still ok provided each run cleans up the mess from the previous crash.

查看更多
干净又极端
5楼-- · 2019-02-03 22:54

You are subscribing to a rather common misconception that heap blocks that are not freed, but still accessible at the time a program exists are leaks. This is not true. Leaked blocks are those which no pointer still references, hence they can't be freed.

Through the years of playing with (and breaking) lots of perfectly good kernels, I have never managed to sufficiently break a virtual memory manager to the point where it no longer reclaimed the entire address space of a process once it exited. Unless you are working with a kernel clearly marked as 'new and experimental', you will have better luck winning the lottery than finding a system that doesn't employ an effective virtual memory manager.

Don't put cruft in your code just to get a perfect score in Valgrind. If you have no real clean up tasks to do other than freeing memory that still has valid references, you don't need to bother. If someone throws a kill -9 to your program, you won't be able to handle it and will see the old behavior repeat.

If you have file descriptors to clean up, shared locks to relinquish, streams to flush or whatever else must happen so other processes don't miss you when you're gone, by all means take care of that. Just don't go adding code that does nothing to solve a non-problem, it just seems silly to do so.

Note

This was originally going to be a comment, but is far too long and SO frowns on writing a novel one comment at a time.

查看更多
叛逆
6楼-- · 2019-02-03 23:08

Pressing CtrlC will send a SIGINT to the process, which by default does a mostly-orderly shutdown, including tearing down the memory manager and releasing all allocated heap and stack. If you need to perform other tasks then you will need to install a SIGINT handler and perform those tasks yourself.

查看更多
7楼-- · 2019-02-03 23:09

In a virtual-memory-based system, all memory is returned to the OS when a process is terminated, regardless of whether it was freed explicitly in the application code. The same might not be true of other resources, however, which you may want to free cleanly. In which case, you need to provide a custom signal handler for the SIGINT signal (which is received on Ctrl+C), see e.g. http://linux.die.net/man/2/sigaction.

查看更多
登录 后发表回答