Memory leaks occur if exit(exitcode) in C? [duplicate] - c

This question already has answers here:
dangers of _exit() - memory leak?
(3 answers)
Closed 9 years ago.
In C program, if there are dynamically allocated memories remained not freed after the execution of the program exit with exit(100);, do we get memory leaks problem? For example:
int main (void) {
char str1[] = "Hello World"
char *str2;
str2 = malloc(strlen(str1 + 1));
if (str2)
exit(101); // memory leaks?
free(str2);
return 0;
}

Not under modern operating systems, no. The OS automatically collects all the memory when the process dies.
In fact freeing memory can actually be detrimental for the performance if the program is exiting anyway. The reason is that calling free sometimes involves a lot of work - updating a lot of structures, touching cache lines etc. By simply exiting you don't do all this userspace nonsense and the OS takes care of actually unmapping your data.

All dyanmically allocated memory allocated using malloc needs to be freed explicitly by calling free. While your program keeps running the memory unallocated this way might be called a leak(provided it is not being used at all).However, once your program/process returns the OS simply reclaims the memory it allocated to the process. The OS does not understand leak it simply reclaims back what it gave to the process.

This depends on the operating system. All modern operating systems (to my knowledge) will free memory not explicitly freed by the C program when it has completed execution. Thus, you can get away with this without consequences under normal circumstances. In fact, there are some schools of thought that do not recommend releasing memory when program execution will end soon as it is unnecessary. However, if you happen to be dealing with old or unusual operating systems that can be dangerous. In some of those systems, it can take a restart to free the memory again.

Related

C malloc and free

I was taught that if you do malloc(), but you don't free(), the memory will stay taken until a restart happens. Well, I of course tested it. A very simple code:
#include <stdlib.h>
int main(void)
{
while (1) malloc(1000);
}
And I watched over it in Task Manager (Windows 8.1).
Well, the program took up 2037.4 MB really quickly and just stayed like that. I understand it's probably Windows limiting the program.
But here is the weird part: When I closed the console, the memory use percentage went down, even though I was taught that it isn't supposed to!
Is it redundant to call free, since the operating system frees it up anyway?
(The question over here is related, but doesn't quite answer whether I should free or not.)
On Windows, a 32 bit process can only allocate 2048 megabytes because that's how many addresses are there. Some of this memory is probably reserved by Windows, so the total figure is lower. malloc returns a null pointer when it fails, which is likely what happens at that point. You could modify your program like this to see that:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int counter = 0;
while (1) {
counter++;
if (malloc(1000) == NULL) {
printf("malloc failed after %d calls\n", counter);
return 0;
}
}
}
Now you should get output like this:
$ ./mem
malloc failed after 3921373 calls
When a process terminates or when it is terminated from the outside (as you do by killing it through the task manager), all memory allocated by the process is released. The operating system manages what memory belongs to what process and can therefore free the memory of a process when it terminates. The operating system does not however know how each process uses the memory it requested from the operating system and depends on the process telling it when it doesn't need a chunk of memory anymore.
Why do you need free() then? Well, this only happens on program termination and does not discriminate between memory you still need and memory you don't need any more. When your process is doing complicated things, it is often constantly allocating and releasing memory for its own computations. It's important to release memory explicitly with free() because otherwise your process might at some point no longer be able to allocate new memory and crashes. It's also good programming practice to release memory when you can so your process does not unnecessarily eat up tons of memory. Instead, other processes can use that memory.
It is advisable to call free after you are done with the memory you had allocated, as you may need this memory space later in your program and it will be a problem if there was no memory space for new allocations.
You should always seek portability for your code.If windows frees this space, may be other operating systems don't.
Every process in the Operating System have a limited amount of addressable memory called the Process Address Space. If you allocate a huge amount of memory and you end up allocating all of the memory available for this process, malloc will fail and return NULL. And you will not be able to allocate memory for this process anymore.
With all non-trivial OS, process resources are reclaimed by the OS upon process termination.
Unless there is specifc and overriding reason to explicitly free memory upon termination, you don't need to do it and you should not try for at least these reasons:
1) You would need to write code to do it, and test it, and debug it. Why do this, if the OS can do it? It's not just redundant, it reduces quality because your explict resource-releasing will never get as much testing as the OS has already had before it got released.
2) With a complex app, with a GUI and many subsystems and threads, cleanly freeing memory on shutdown is nigh-on impossible anyway, which leads to:
3) Many library developers have already given up on the 'you must explicitly release blah... ' mantra because the complexity would result in the libs never being released. Many report unreleased, (but not lost), memory to valgrid and, with opaque libs, you can do nothing at all about it.
4) You must not free any memory that is in use by a running thread. To safely release all such memory in multithreaded apps, you must ensure that all process threads are stopped and cannot run again. User code does not have the tools to do this, the OS does. It is therefore not possible to explicitly free memory from user code in any kind of safe manner in such apps.
5) The OS can free off the process memory in big chunks - much more quickly than messing around with dozens of sub-allcations in the C manager.
6) If the process is being terminated because it has failed due to memory management issues, calling free() many more times is not going to help at all.
7) Many teachers and profs say that you must explicity free the memory, so it's obviously a bad plan.

Heap memory allocation

If I allocate memory dynamically in my program using malloc() but I don't free the memory during program runtime, will the dynamically allocated memory be freed after program terminates?
Or if it is not freed, and I execute the same program over and over again, will it allocate the different block of memory every time? If that is the case, how should I free that memory?
Note: one answer I could think of is rebooting the machine on which I am executing the program. But if I am executing the program on a remote machine and rebooting is not an option?
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
#endif
char **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.
If I allocate memory dynamically in my program using malloc() but I
don't free the memory during program runtime, will the dynamically
allocated memory be freed after program terminates?
The operating system will release the memory allocated through malloc to be available to other systems.
This is much more complex than your question makes it sound, as the physical memory used by a process may be written to disk (paged-out). But with both Windows, Unix (Linux, MAC OS X, iOS, android) the system will free the resources it has committed to the process.
Or if it is not freed, and I execute the same program over and over
again, will it allocate the different block of memory every time? If
that is the case, how should I free that memory?
Each launch of the program, gets a new set of memory. This is taken from the system, and provided as virtual addresses. Modern operating systems use address-space-layout-randomization (ASLR) as a security feature, this means that the heap should provide unique addresses each time your program launches. But as the resources from other runs have been tidied up, there is no need to free that memory.
As you have noted, if there is no way for a subsequent run to track where it has committed resources, how is it expected to be able to free them.
Also note, you can run your program multiple launches that run at the same time. The memory allocated may appear to overlap - each program may see the same address allocated, but that is "virtual memory" - the operating system has set each process up independently so it appears to use the same memory, but the RAM associated with each process would be independent.
Not freeing the memory of a program when it executes will "work" on Windows and Unix, and probably any other reasonable operating system.
Benefits of not freeing memory
The operating system keeps a list of large memory chunks allocated to the process, and also the malloc library keeps tables of small chunks of memory allocated to malloc.
By not freeing the memory, you will save the work accounting for these small lists when the process terminates. This is even recommended in some cases (e.g. MSDN : Service Control Handler suggests SERVICE_CONTROL_SHUTDOWN should be handled by NOT freeing memory)
Disadvantages of not freeing memory
Programs such as valgrind and application verifier check for program correctness by monitoring the memory allocated to a process and reporting on leaks.
When you don't free the memory, these will report a lot of noise, making unintentional leaks difficult to find. This would be important, if you were leaking memory inside a loop, which would limit the size of task your program could deliver.
Several times in my career, I have converted a process to a shared object/dll. These were problematic conversions, because of leaks that were expected to be handled by the OS process termination, started to survive beyond the life of "main".
As we say brain of the Operating system is kernel. Operating system has several responsibilities.
Memory Management is a function of kernel.
Kernel has full access to the system's memory and must allow processes
to safely access this memory as they require it.
Often the first step in doing this is virtual addressing, usually achieved by paging and/or segmentation. Virtual addressing allows the kernel to make a given physical address appear to be another address, the virtual address. Virtual address spaces may be different for different processes; the memory that one process accesses at a particular (virtual) address may be different memory from what another process accesses at the same address.
This allows every program to behave as if it is the only one (apart
from the kernel) running and thus prevents applications from crashing
each other
Memory Allocation
malloc
Allocate block of memory from heap
. .NET Equivalent: Not applicable. To call the standard C function, use PInvoke.
The Heap
The heap is a region of your computer's memory that is not managed
automatically for you, and is not as tightly managed by the CPU. It is
a more free-floating region of memory (and is larger). To allocate
memory on the heap, you must use malloc() or calloc(), which are
built-in C functions. Once you have allocated memory on the heap, you
are responsible for using free() to deallocate that memory once you
don't need it any more. If you fail to do this, your program will have
what is known as a memory leak. That is, memory on the heap will
still be set aside (and won't be available to other processes).
Memory Leak
For Windows
A memory leak occurs when a process allocates memory from the paged or nonpaged pools, but does not free the memory. As a result, these limited pools of memory are depleted over time, causing Windows to slow down. If memory is completely depleted, failures may result.
Determining Whether a Leak Exists describes a technique you can use
if you are not sure whether there is a memory leak on your system.
Finding a Kernel-Mode Memory Leak describes how to find a leak that
is caused by a kernel-mode driver or component.
Finding a User-Mode Memory Leak describes how to find a leak that is
caused by a user-mode driver or application.
Preventing Memory Leaks in Windows Applications
Memory leaks are a class of bugs where the application fails to release memory when no longer needed. Over time, memory leaks affect the performance of both the particular application as well as the operating system. A large leak might result in unacceptable response times due to excessive paging. Eventually the application as well as other parts of the operating system will experience failures.
Windows will free all memory allocated by the application on process
termination, so short-running applications will not affect overall
system performance significantly. However, leaks in long-running
processes like services or even Explorer plug-ins can greatly impact
system reliability and might force the user to reboot Windows in order
to make the system usable again.
Applications can allocate memory on their behalf by multiple means. Each type of allocation can result in a leak if not freed after use
. Here are some examples of common allocation patterns:
Heap memory via the HeapAlloc function or its C/C++ runtime
equivalents malloc or new
Direct allocations from the operating system via the VirtualAlloc
function.
Kernel handles created via Kernel32 APIs such as CreateFile,
CreateEvent, or CreateThread, hold kernel memory on behalf of the
application
GDI and USER handles created via User32 and Gdi32 APIs (by default,
each process has a quota of 10,000 handles)
For Linux
memprof is a tool for profiling memory usage and finding memory leaks.
It can generate a profile how much memory was allocated by each
function in your program. Also, it can scan memory and find blocks
that you’ve allocated but are no longer referenced anywhere.
Memory allocated by the malloc needs to be freed by the allocating program.If not and memory is kept on being allocated then one point will come that the program will run out of allowable memory allocation and throw a segmentation or out of memory error. Every set of memory allocation by malloc needs to be accompanied by free.

Intricacies of malloc and free

I have two related questions hence I am asking them in this single thread.
Q1) How can I confirm if my OS is clearing un-"free"'ed memory (allocated using malloc) automatically when a program terminates? I am using Ubuntu 11.04, 32-bit with gcc-4.5.2
As per a tutorial page by Steven Summit here, "Freeing unused memory (malloc'ed) is a good idea, but it's not mandatory. When your program exits, any memory which it has allocated but not freed should be automatically released. If your computer were to somehow ``lose'' memory just because your program forgot to free it, that would indicate a problem or deficiency in your operating system."
Q2) Suppose, foo.c mallocs a B-bytes memory. Later on, foo.c frees this B-bytes memory locations and returns it to the OS. Now my question is, can those PARTICULAR B-bytes of memory locations be re-allocated to foo.c (by the OS) in the current instance OR those B-bytes can't be allocated to foo.c untill its current instance terminates ?
EDIT : I would recommend everyone who reads my question to read the answer to a similar question here and here. Both answers explain the interaction and working of malloc() and free() in good detail without using very esoteric terms. To understand the DIFFERENCE between memory-management tools used by kernel (e.g. brk(), mmap()) and those used by the C-compiler (e.g. malloc(), free()), this is a MUST READ.
When a process ends either thru a terminating signal, e.g. SIGSEGV, or thru the _exit(2) system call (which happens to be called also when returning from main), all the process resources are released by the kernel. In particular, the process address space, including heap memory (allocated with mmap(2) (or perhaps sbrk(2)) syscall (used by malloc library function) is released.
Of course, the free library function either (often) makes the freed memory zone reusable by further future calls to malloc or (occasionally, for large memory zones) release some big memory chunk to the kernel using e.g. munmap(2) system call.
To know more about the memory map of process 1234, read sequentially the /proc/1234/maps pseudo-file (or /proc/self/maps from inside the process). The /proc file system is the preferred way to query the kernel about processes. (there is also /proc/self/statm and /proc/self/smaps and many other interesting things).
The detailed behavior of free and malloc is implementation dependent. You should view malloc as a way to get heap memory, and free as a way to say that a previously malloc-ed zone is useless, and the system (i.e. standard C library + kernel) can do whatever it wants with it.
Use valgrind to hunt memory leak bugs. You could also consider using Boehm's conservative garbage collector, i.e. use GC_malloc instead of malloc and don't bother about freeing manually memory.
Most Modern OS will reclaim the allocated memory so you need not worry about that.
The OS doesn't understand if your application/program leaked memory or not it simply reclaims what it allocated to an process once the process completes.
Yes freed memory can be reused(if needed) & the reuse can happen in the same instantiation.
Q1. You just have to assume that the operating system is behaving correctly.
Q2. There is no reason why the bytes can't be reallocated to foo.c it just depends on how the memory allocation routines work.
Q1) I'm not sure about how you can confirm. However, about the second paragraph, it's considered good style to always free whatever memory you allocate. A good explanation of this is found here: What REALLY happens when you don't free after malloc?.
Q2) Definitely; those bytes are usually the first to be reallocated (depending on the malloc implementation). For a great explanation, see: How do malloc() and free() work?.

Does OS reclaim memory on application exit in C? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When you exit a C application, is the malloc-ed memory automatically freed?
Pretty much the title. Do (modern) OSs automatically reclaim heap-allocated memory on program termination? If so, is freeing the memory a strict must or more of a just-follow-the-damn- standard-you-fool kinda thing?
What is the worst thing than can happen if I do not explicitly free the memory except that I end up wasting it while the application is in run?
When an application terminates, all memory will be reclaimed by the OS. The reason people preach memory management techniques is because so long as the app is running, any memory it's asked for will remain in its posession (even if it's no longer being used). Unless, of course, you were nice enough to call free.
if the app terminates the os will clean up the memory and resources.
if you do not clean up memory with free( ) then heap-allocated memory will be used up as you request more and more. if it continues, the os will start using swap/page file to allocate. it u still continue os will grind down to a halt, or terminate the app with some kind of error
Does OS reclaim memory on application exit in C? Yes.
If you don't free memory: your application may run out of memory & crash.
Freeing memory before exiting is optional because the o/s will clean up for you.
Freeing unused memory while running is a good idea; it prevents the application from running out of memory (and having to exit). The difficulty is often working out which memory is unused.
Yes. But if your program is a long running program, you not only crash your program eventually, but as the time progresses, you will also slowdown the system, assuming you use too much memory.

C malloc() memory space released after program ends? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What REALLY happens when you don't free after malloc?
Is freeing allocated memory needed when exiting a program in C
During my first C class, it was drilled into me that I should call free() after malloc() or calloc() as it releases the space after dynamically allocating memory or otherwise it will be gone (I assume until system reboot). However, recently I started reading on various coding sites that this memory will be released back when the program ends.
Which one is the correct statement?
I would look in the official spec, but I have no idea where to get it (tried Googling).
Thanks.
Really short answer..
Both of the statements are correct.
A longer more elaborate one..
Both of them are correct, when your application fully terminates the allocated memory will (probably) be released back to the system.
I wrote "probably" since all modern/widely-used OSes will deallocate the memory used, but some primitive systems might not have this "feature" available.
Because of the above you should always use free to deallocate memory of allocated but unused variables, especially during run-time (otherwise you'll have a memory leak that might/will slowly eat up all available memory).
If you wanna live on the wild side and not deallocate memory before the application terminates, that's fine by me and most people.B ut, please make sure that the platform you are going to run the application in really does release the memory back to the operating system afterwards.
Regarding looking in the standard ("official spec")
The standard most often/always leaves out implementation details, therefor there is nothing in there saying what will happen to allocated memory that hasn't been deallocated when the running application terminates.
That's implementation specific, and therefor depends in/on/at what you are running it.
On any system with protected memory (e.g. Windows 4.x+, Linux, Unix, …), the memory is released when the program terminates.
Some embedded systems may not always do so, however.
Regardless, it's definitely good form to free() everything correctly.
This is valid within the program, that's while the process is running.
Out of it, this is OS dependent. There is no spec, but the big majority of systems will clean up all the memory used by the process after it is finished.
All memory for a given process is released back to the system at its termination. However, before a program exits, it's important to always free() your memory, especially for long-running programs. In short-running programs, it's still good practice. It's always nice when valgrind spits out a clean bill of health!

Resources