Heap memory allocation Heap memory allocation c c

Heap memory allocation


Short answer: Once your process terminates, any reasonable operating system is going to free all memory allocated by that process. So no, memory allocations will not accumulate when you re-start your process several times.


Process and memory management are typically a responsibility of the operating system, so whether allocated memory is freed or not after a process terminates is actually dependent on the operating system. Different operating systems can handle memory management differently.

That being said, any reasonable operating system (especially a multi-tasking one) is going to free all of the memory that a process allocated once that process terminates.

I assume the reason behind this is that an operating system has to be able to gracefully handle irregular situations:

  • malicious programs (e.g. those that don't free their memory intentionally, in the hope of affecting the system they run on)
  • abnormal program terminations (i.e. situations where a program ends unexpectedly and therefore might not get a chance to explicitly free its dynamically allocated memory itself)

Any operating system worth its salt has to be able to deal with such situations. It has to isolate other parts of the system (e.g. itself and other running processes) from a faulty process. If it did not, a process' memory leak would propagate to the system. Meaning that the OS would leak memory (which is usually considered a bug).

One way to protect the system from memory leaks is by ensuring that once a process ends, all the memory (and possibly other resources) that it used get freed.


Any memory a program allocated should be freed when the program terminates, regardless of whether it's allocated statically or dynamically. The main exception to this is if the process is forked to another process.

If you do not explicitly free any memory you malloc, it will stay allocated until the process is terminated.


Even if your OS does cleanup on exit(). The syscall to exit is often wrapped by an exit() function. Here is some pseudo code, derived from studying several libc implementations, to demonstrate what happens around main() that could cause a problem.

//unfortunately gcc has no builtin for stack pointer, so we use assembly#ifdef __x86_64__   #define STACK_POINTER "rsp"#elif defined __i386__   #define STACK_POINTER "esp"#elif defined __aarch64__   #define STACK_POINTER "x13"#elif defined __arm__   #define STACK_POINTER "r13"#else  #define STACK_POINTER "sp" //most commonly used name on other arches#endifchar **environ;void exit(int);int main(int,char**,char**); _Noreturn void _start(void){    register long *sp __asm__( STACK_POINTER );    //if you don't use argc, argv or envp/environ, just remove them   long argc = *sp;   char **argv = (char **)(sp + 1);   environ = (char **)(sp + argc + 1);   //init routines for threads, dynamic linker, etc... go here   exit(main((int)argc, argv, environ));   __builtin_unreachable(); //or for(;;); to shut up compiler warnings}

Notice that exit is called using the return value of main. On a static build without a dynamic linker or threads, exit() can be a directly inlined syscall(__NR_exit,main(...)); however if your libc uses a wrapper for exit() that does *_fini() routines (most libc implementations do), there is still 1 function to call after main() terminates.

A malicious program could LD_PRELOAD exit() or any of the routines it calls and turn it into a sort of zombie process that would never have its memory freed.

Even if you do free() before exit() the process is still going to consume some memory (basically the size of the executable and to some extent the shared libraries that aren't used by other processes), but some operating systems can re-use the non-malloc()ed memory for subsequent loads of that same program such that you could run for months without noticing the zombies.

FWIW, most libc implementations do have some kind of exit() wrapper with the exception of dietlibc (when built as a static library) and my partial, static-only libc.h that I've only posted on the Puppy Linux Forum.