简体   繁体   中英

What is the need of deallocating memory in C?

I may be misinformed, but to my knowledge the OS cleans up memory after a program quits or crashes.

If so, how useful is it to deallocate memory at the end of a program? I understand that if a program is running and deallocating is neglected that memory could become "full", but if a program is already going to end and the OS deallocates all memory used by the program, what is the point of deallocating that memory manually?

Cleanliness.

You could, of course, not bother going through your cleanup and let the system handle it. However, if you do this it is essentially impossible for you to trace memory leaks in your program since you can't run it and see whether anything is left allocated at the end. If, on the other hand, you ensure a clean shutdown you can know whether there are any leaks by running it and seeing whether anything is left allocated at the end. Since for any non-trivial program likely to be running for some time memory leaks are something to avoid, doing it in this clean fashion leads to benefits.

Additionally, it's also just part of ensuring your program shuts down cleanly with any persistent state left in the right condition and any external resources freed (although most modern OSs will clean that up these days) because you're going through an orderly shutdown rather than just cutting and running.

Quoting from Memory Deallocation Issues in C :

The operating system is responsible for maintaining the resources of an application, including its memory. When an application terminates, it is the operating system's responsibility to reallocate this memory for other applications. The state of the terminated application's memory, corrupted or uncorrupted, is not an issue. In fact, one of the reasons an application may terminate is because its memory is corrupted. With an abnormal program termination, cleanup may not be possible.

With this said, there may be other reasons why memory should be freed when a program terminates normally:

  • The conscientious programmer may want to free memory as a quality issue. It is always a good habit to free memory after it is no longer needed, even if the application is terminating.
  • If you use a tool to detect memory leaks or similar problems, then deallocating memory will clean up the output of such tools.
  • In some less complex operating systems, the operating system may not reclaim memory automatically, and it may be the program's responsibility to reclaim memory before terminating.
  • Also, a later version of the application could add code toward the end of the program. If the previous memory has not been freed, problems could arise.

Different perspective:

At the end of your program, there's generally no specific practical reason to clean up memory. But that's not how you usually design non-trivial programs that don't fit on a single page! The parts of a program normally need to be designed to work well no matter when they run in the course of program execution, and usually without knowledge of the rest of the program. They can't permanently allocate and hog memory because in general, they don't know how often they'll be called, or how much code will follow them, or for how long. Many end-user applications are designed to run a potentially-infinite "main loop", after all.

So a program that cleans up completely after itself isn't a goal, it's one of the lesser consequences (a reward for the obsessive!) of designing your whole program properly from the ground up. It may also serve as a warning flag that some stage of the design process didn't go to plan if there are resources left over at the end.

You cannot always depend on system, although most modern ones do it. AFAIK Windows 95 didn't do it, so maybe some wild, embedded systems out there also do not clean up after processes.

Other than that, it's a good habit. Sometimes you will refactor things from main into some modules and try to reuse them. It's good not to forget to deallocate things then.

Yep. That's right. If there's some object that will live for the entire duration of the application, it's reasonable to allocate it once on startup and never free/delete the object. However, if you allocate something as part of a computation where there is no need to retain the object for the entire lifetime of the program, then it is important to free the object when it is no longer needed; otherwise, your program will slowly run out of available memory as objects are leaked over the program's lifetime.

It should be noted that even if you do free your memory, there is always a possibility that your program will be forcibly terminated (eg by a signal) before you have a chance to free the memory. So, that is one reason to not be super paranoid about it. That being said, for consistency and maintaining good habits both for regular allocations/deallocations as well allocations/deallocations of long-lived objects, I generally prefer to free/cleanup long lived objects much like regular objects. That being said, you should balance the desire to be clean with quick shutdown and the ability to produce proper core dumps / logs in the event of a forced shutdown. For example, taking the time to free large long-lived data structures may come at the expense of having time to write a core dump, in which case it is probably better to write the core.

In general, if you do not deallocate your memory when it is no longer needed, you can exhaust the system's memory resources. This is what's known as a memory leak.

This is most evident in programs that run for a long period of time... as they run and allocate more and more memory (eg, call malloc), more and more memory resources are consumed by the program. If they are not returned to the system, then the operating system can start to run out of memory to give to its applications when 'malloc' is called.

Certain operating systems and programming languages have features that can either mitigate or prevent this from happening.

Java, for example, doesn't allow you to directly call malloc and free. Instead, as you create objects, memory is allocated for them by the java runtime. When you are done with variables (ie, when they go "out of scope"), they are marked for "garbage collection". Normally, a "garbage collection" task or function will run periodically and will call free on all of the memory associated with variables that are no longer used (ie, "cleans up the garbage").

Some operating systems also support run-time limits on processes and/or threads that prevent them from consuming "all" of the system resources. If any of these limits are hit, the operating system can halt the execution of the program.

Hope that helps, - J.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM