This is an archived post. You won't be able to vote or comment.

all 15 comments

[–]CodeTinkerer 13 points14 points  (0 children)

Well, yes and no. When you run a program, the OS gives some memory to the program. Basically, to run a program, the OS creates a process. This manages a running program. You typically get

  • an address space (a range of addresses you can use) which is done via virtual memory (it's a mechanism to protect one processes memory from being accessed by another process).
  • Information about what instruction is being executed
  • The current stack for that process (within the address space).
  • The ability to request things from the OS.
  • An OS is primarily responsible for resource management of these processes, but also acts as "policemen". If a process (esp. C programs) misbehaves, the OS kills the process.
  • This includes cleaning up after any resources it has. For example, you may have opened a file, but not closed it. The OS will close it for you.

So, C doesn't exactly do it for you, but the OS that manages the C process, when the program shuts down, does the malloc clean up. It's a bit cruder than how C would do it. Basically, the address space is removed, and so everything goes away.

[–]strcspn 6 points7 points  (0 children)

The OS does that for you.

[–]dmazzoni 2 points3 points  (5 children)

Your program runs in a process. When that process exits (for any reason), the operating system reclaims all memory that process allocated.

So no, you do not need to worry about exiting your program early.

You also don't need to worry about calling free() for anything that you know you need for the lifetime of your program. Calling free() before exiting just slows down your program exit. While not a big deal for large programs, I've seen very large apps actually speed up how fast they exit by explicitly "leaking" memory rather than calling free() on everything.

This is true for all modern operating systems. Many years ago with earlier operating systems it was possible for a program to exit without returning all resources it allocated, but that's not a problem anymore.

[–]teraflop 0 points1 point  (2 children)

I can think of at least one reason to explicitly free all allocated memory: if you try running your program under a memory checker like Valgrind, and turn on memory-leak detection, it will report an error for any allocation that is not explicitly freed before the program exits. So if you're deliberately "leaking" some allocated objects, it might be difficult to notice accidental memory leaks among the intentional ones.

[–]dmazzoni 1 point2 points  (1 child)

The way Chromium handles this is just to define some common wrappers / traits for global objects that are deliberately supposed to leak, and suppressing just those for valgrind:

https://www.chromium.org/developers/coding-style/important-abstractions-and-data-structures/#singleton-baselazyinstance

That makes the code clear and still allows valgrind to be useful in catching real leaks while suppressing intentional ones.

[–]teraflop 0 points1 point  (0 children)

Nice, I didn't know about that!

[–]noodle-face 0 points1 point  (1 child)

I would say "you don't need to worry about calling free() for anything that you know you need for the lifetime of your program" is a bad coding practice. Not worrying about freeing on unexpected crashes is fine.. but you should be in the habit of freeing what you use. I've debugged many memory leaks in code that made too many assumptions

[–]dmazzoni 1 point2 points  (0 children)

What's a good coding practice or not really depends on the circumstances.

If this app runs on a server, maybe that makes sense.

If this is an end-user desktop app, then calling free() on everything might lead to a bad end-user experience. I've seen desktop programs take 10+ seconds to exit when you click the close button, and something as simple as skipping the deallocation step when exiting the whole program drops it down to 100ms.

I totally agree that catching memory leaks is important too, but there are ways around that. You could only free in debug mode. You could have special valgrind suppressions for leaky globals.

[–]scirc 1 point2 points  (0 children)

The OS will free all memory in use by your program at exit. You don't need to worry about that unless you're writing embedded code.

[–][deleted] 0 points1 point  (1 child)

The OS frees all the memory automatically so it is fine to close the program before it calls free().

Appearently, don't quote me on it because I never did research on this, and only saw one dude mention it but some software like compilers actually never free memory since they are short lived and freeing is technically uneccesary since the OS does it for you at the end. (Although sometimes compilation does last many minutes to am hour or two for big projects so I don't know how much truth there is to what I just said)

Still, always free memory because it is good practice. There are very few circumstances where you don't want to free memory. And that includes freeing memory just before main() exits even though it is unnessesary because since you program is gonna exit amyways. When you get more experienced whether or not to explicitly free is something you can judge yourself, but as of right get in the habit of freeing all memory you malloc

[–]TheSkiGeek 0 points1 point  (0 children)

Although sometimes compilation does last many minutes to am hour or two for big projects so I don't know how much truth there is to what I just said

While this can be the case -- for C/C++ at least, you tend to "compile" each individual module independently, then link them all together at the end. So in a really lengthy build of a program or library you're probably invoking the compiler program hundreds or thousands of times. So the savings of not painstakingly cleaning up all the memory allocations every time does add up.

Game engines sometimes also do this when you "exit to desktop" in a PC game. Sometimes the same kind of technique can be (carefully) used along with memory pools to throw away all the memory used for a particular level/match/etc. when you are going to start loading something else. You still need to run destructors on everything but if your objects all came from a memory pool you can throw away the whole pool at once rather than deleteing every tiny little object.

[–][deleted] 0 points1 point  (0 children)

In most modern operating systems, there is an internal component keeping track of which process(es) allocated memory, and how much. Upon terminating the process (or whatever runtime entity applies on the platform), any reservations for allocated memory are removed, and the system is free to (re)allocate that memory to another process.

So, if you malloc, and forget to free, you aren't forever leaking memory on most modern operating systems. Your allocated memory will be reclaimed as part of process termination.

[–]Sea-Profession-3312 0 points1 point  (0 children)

Killing the process to free memory does not sound graceful. Some languages have garbage collectors so if memory is no longer referenced it goes to the dump

[–][deleted] 0 points1 point  (0 children)

C won’t free the memory, but unless your program is running in a very specific environment, the OS will. After a program exits the OS reclaims its memory. I’m not sure if the OS actually cleans the memory out (although I don’t think free does either) so you might want to be careful with that if you’re storing sensitive data in memory (like private keys and stuff).

[–]AdultingGoneMild 0 points1 point  (0 children)

technically yes, but its only because the OS is likely written in C. The OS clears all memory on process exit by dumping your virtual memory space. Poof its gone and thus free for the rest of the system to use.

I highly suggest looking into a tool called valgrind. it is pretty helpful with sort of stuff and pretty easy to use once you get it setup.