Is memory being freed when calling exec(3) an implementation detail? - c

From what I've read, the general consensus seems to be that you don't need to free memory before running exec(3). However, in the POSIX standard, handling of the heap / malloc memory does not seem to be explicitly detailed. I know it's common for people to not bother freeing memory when an application is exiting because the OS will clean up the data, but from what I understand, that's an OS implementation detail; the OS is not required to free the memory even though many modern systems do. Is this also the case with exec(3)? I'm wondering if freeing malloc'd memory before exec(3) is the right thing to do even though it's not necessary for many modern operating systems.

No, this is not an implementation detail. The freeing of memory is implicit in the definition of the exec function family:
The exec family of functions shall replace the current process image with a new process image.
The POSIX standard doesn't appear to have a clear definition of "process image", but from context, it's pretty clear that this includes all aspects of process state, including memory allocations.
From a practical standpoint, any system where memory left allocated at exec time was not deallocated would be essentially unusable, as those memory allocations would become unreachable.

Related

Does terminating a program reclaim memory in the same way as free()?

I saw this answer to a stack overflow question that says that freeing memory at the very end of a c program is actually harmful because it moves variables that wouldn't be used again into system memory.
I'm confused why the free() method in C would do anything different than the operating system reclaiming the heap at the end of the program.
Does anyone know if there is a real difference between free() and termination in terms of memory management and if so how the operating system may treat these two differently?
e.g.
would anything different happen between these two short programs?
void main() {
int* mem = malloc(1);
return 0;
}
void main() {
int* mem = malloc(1);
free(mem);
return 0;
}
No, terminating a program, as with exit or abort, does not reclaim memory in the same way as free. Using free causes some activity that ultimately has no effect when the operating system discards the data maintained by malloc and free.
exit has some complications, as it does not immediately terminate the program. For now, let’s just consider the effect of immediately terminating the program and consider the complications later.
In a general-purpose multi-user operating system, when a process is terminated, the operating system releases the memory it was using to make it available for other purposes.1 In large part, this simply means the operating system does some accounting operations.
In contrast, when you call free, software inside the program runs, and it has to look up the size of the memory you are freeing and then insert information about that memory into the pool of memory it is maintaining. There could be thousands or tens of thousands (or more) of such allocations. A program that frees all its data may have to execute many thousands of calls to free. Yet, in the end, when the program exits, all of the changes produced by free will vanish, as the operating system will discard all the data about that pool of memory—all of the data is in memory pages the operating system does not preserve.
So, in this regard, the answer you link to is correct, calling free is a waste. And, as it points out, the necessity of going through all the data structures in the program to fetch the pointers in them so the memory they point to can be freed causes all those data structures to be read into memory if they had been swapped out to disk. For large programs, it can take a considerable amount of time and other resources.
On the other hand, it is not clear it is easy to avoid many calls to free. This is because releasing memory is not the only thing a terminating program has to clean up. A program may want to write final data to files or send final messages to network connections. Furthermore, a program may not have established all of this context directly. Most large programs rely on layers of software, and each software package may have set up its own context, and often no way is provided to tell other software “I want to exit now. Finish the valuable context, but skip all the freeing of memory.” So all the desired clean-up tasks may be interwined with the free-memory tasks, and there may be no good way to untangle them.
Software should generally be written so that nothing terrible happens if a program is suddenly aborted (since this can happen from a loss of power, not just deliberate user action). But even though a program might be able to tolerate an abort, there can still be value in a graceful exit.
Getting back to exit, calling the C exit routine does not exit the program immediately. Exit handlers (registered with atexit) are called, stream buffers are flushed, and streams are closed. Any software libraries you called may have set up their own exit handlers so that they can finish up when the program is exiting. So, if you want to be sure libraries you have used in your program are not calling free when you end the program, you have to call abort, not exit. But it is generally preferred to end a program gracefully, not by aborting. Calling abort will not call exit handlers, flush streams, close streams, or perform other wind-down code that exit does—data can be lost when a program calls abort.
Footnote
1 Releasing memory does not mean it is immediately available for other purposes. The specific result of this depends on each page of memory. For example:
If the memory is shared with other processes, it is still needed for them, so releasing it from use by this process only decrements the number of processes using the memory. It is not immediately available for any other use.
If the memory is not in use by any other processes but contains data mapped from a file on disk, the operating system might mark it as available when needed but leave it alone for the moment. This is because you might run the same program again, and it would be nice if the data were still in memory, so why not just leave it in place just in case? The data might even be used by a different program that uses the same file. (For example, many programs might use the same shared library.)
If the memory is not in use by any other processes and was just used by the program as a work area, not mapped from a file, then system may mark it as immediately available and not containing anything useful.
would anything different happen between these two short programs?
The simple answer is: it makes no difference, the memory is released to the system in both cases. Calling free() is not strictly necessary and does incur an infinitesimal overhead but may prove useful when trying to track memory leaks in more complex programs.
Does terminating a program reclaim memory in the same way as free?
Not exactly:
Terminating a program releases the memory used by the program, be it for the program code, data, stack or heap. It also releases some other resources such as file handles, device handles, network sockets... All this is done efficiently, no matter how many blocks of memory have been allocated with malloc().
Conversely, free() makes the block of memory available for further use by the program for later calls to malloc() or realloc(). Depending on its size and the implementation of the heap, this freed block may or may not be returned to the OS for use by other programs. Also worth noting it the fragmentation problem, where small blocks of freed memory may not be usable for a larger allocation because they are surrounded by allocated blocks. The C heap does not perform packing or de-fragmentation, it merely coalesces adjacent free blocks. Freeing all allocated blocks before leaving the program may be useful for debugging purposes, but may be complicated and time consuming, while not necessary for the memory to be reused by the system after the program terminates.
free() is a user level memory management function and depends on malloc implementation you are currently using. The user-level allocator might maintain a linked-list of memory chunk and malloc/free will take the chunk of appropropriate size/put it back.
exit() Destroys an address space and all regions.
This is related to malloced heap as well as some other regions and in-kernel data structures used for managing address space of the process:
Each address space consists of a number of page-aligned regions
of memory that are in use. They never overlap and represent a set
of addresses which contain pages that are related to each other in
terms of protection and purpose. These regions are represented by
a struct vm_area_struct and are roughly analogous to the
vm_map_entry struct in BSD. For clarity, a region may represent the
process heap for use with malloc(), a memory mapped file such as
a shared library or a block of anonymous memory allocated with
mmap(). The pages for this region may still have to be allocated, be
active and resident or have been paged out
Reference: https://www.kernel.org/doc/gorman/html/understand/understand007.html
The reason well-designed programs free memory at exit is to check for memory leaks. If your application-level memory allocation does not go to zero after your last deallocation, you know that you have a memory memory that is not being managed properly and probably have a memory leak in your code.
would anything different happen between these two short programs?
YES
I'm confused why the free() method in C would do anything different than the operating system reclaiming the heap at the end of the program.
The operating system allocates memory in pages. Heap managers (such as malloc/free implementations) allocate pages from the operating system and subdivide the pages into smaller allocations. Calls to free() normally return memory to the heap. They do not return the pages to the operating system.

When do you consider a programme is leaking, and do you have to free before exit? [duplicate]

We are all taught that you MUST free every pointer that is allocated. I'm a bit curious, though, about the real cost of not freeing memory. In some obvious cases, like when malloc() is called inside a loop or part of a thread execution, it's very important to free so there are no memory leaks. But consider the following two examples:
First, if I have code that's something like this:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
What's the real result here? My thinking is that the process dies and then the heap space is gone anyway so there's no harm in missing the call to free (however, I do recognize the importance of having it anyway for closure, maintainability, and good practice). Am I right in this thinking?
Second, let's say I have a program that acts a bit like a shell. Users can declare variables like aaa = 123 and those are stored in some dynamic data structure for later use. Clearly, it seems obvious that you'd use some solution that will calls some *alloc function (hashmap, linked list, something like that). For this kind of program, it doesn't make sense to ever free after calling malloc because these variables must be present at all times during the program's execution and there's no good way (that I can see) to implement this with statically allocated space. Is it bad design to have a bunch of memory that's allocated but only freed as part of the process ending? If so, what's the alternative?
Just about every modern operating system will recover all the allocated memory space after a program exits. The only exception I can think of might be something like Palm OS where the program's static storage and runtime memory are pretty much the same thing, so not freeing might cause the program to take up more storage. (I'm only speculating here.)
So generally, there's no harm in it, except the runtime cost of having more storage than you need. Certainly in the example you give, you want to keep the memory for a variable that might be used until it's cleared.
However, it's considered good style to free memory as soon as you don't need it any more, and to free anything you still have around on program exit. It's more of an exercise in knowing what memory you're using, and thinking about whether you still need it. If you don't keep track, you might have memory leaks.
On the other hand, the similar admonition to close your files on exit has a much more concrete result - if you don't, the data you wrote to them might not get flushed, or if they're a temp file, they might not get deleted when you're done. Also, database handles should have their transactions committed and then closed when you're done with them. Similarly, if you're using an object oriented language like C++ or Objective C, not freeing an object when you're done with it will mean the destructor will never get called, and any resources the class is responsible might not get cleaned up.
Yes you are right, your example doesn't do any harm (at least not on most modern operating systems). All the memory allocated by your process will be recovered by the operating system once the process exits.
Source: Allocation and GC Myths (PostScript alert!)
Allocation Myth 4: Non-garbage-collected programs
should always deallocate all memory
they allocate.
The Truth: Omitted
deallocations in frequently executed
code cause growing leaks. They are
rarely acceptable. but Programs that
retain most allocated memory until
program exit often perform better
without any intervening deallocation.
Malloc is much easier to implement if
there is no free.
In most cases, deallocating memory
just before program exit is pointless.
The OS will reclaim it anyway. Free
will touch and page in the dead
objects; the OS won't.
Consequence: Be careful with "leak
detectors" that count allocations.
Some "leaks" are good!
That said, you should really try to avoid all memory leaks!
Second question: your design is ok. If you need to store something until your application exits then its ok to do this with dynamic memory allocation. If you don't know the required size upfront, you can't use statically allocated memory.
=== What about future proofing and code reuse? ===
If you don't write the code to free the objects, then you are limiting the code to only being safe to use when you can depend on the memory being free'd by the process being closed ... i.e. small one-time use projects or "throw-away"[1] projects)... where you know when the process will end.
If you do write the code that free()s all your dynamically allocated memory, then you are future proofing the code and letting others use it in a larger project.
[1] regarding "throw-away" projects. Code used in "Throw-away" projects has a way of not being thrown away. Next thing you know ten years have passed and your "throw-away" code is still being used).
I heard a story about some guy who wrote some code just for fun to make his hardware work better. He said "just a hobby, won't be big and professional". Years later lots of people are using his "hobby" code.
You are correct, no harm is done and it's faster to just exit
There are various reasons for this:
All desktop and server environments simply release the entire memory space on exit(). They are unaware of program-internal data structures such as heaps.
Almost all free() implementations do not ever return memory to the operating system anyway.
More importantly, it's a waste of time when done right before exit(). At exit, memory pages and swap space are simply released. By contrast, a series of free() calls will burn CPU time and can result in disk paging operations, cache misses, and cache evictions.
Regarding the possiblility of future code reuse justifing the certainty of pointless ops: that's a consideration but it's arguably not the Agile way. YAGNI!
I completely disagree with everyone who says OP is correct or there is no harm.
Everyone is talking about a modern and/or legacy OS's.
But what if I'm in an environment where I simply have no OS?
Where there isn't anything?
Imagine now you are using thread styled interrupts and allocate memory.
In the C standard ISO/IEC:9899 is the lifetime of memory stated as:
7.20.3 Memory management functions
1 The order and contiguity of storage allocated by successive calls to the calloc,
malloc, and realloc functions is unspecified. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an allocated object extends
from the allocation until the deallocation.[...]
So it has not to be given that the environment is doing the freeing job for you.
Otherwise it would be added to the last sentence: "Or until the program terminates."
So in other words:
Not freeing memory is not just bad practice. It produces non portable and not C conform code.
Which can at least be seen as 'correct, if the following: [...], is supported by environment'.
But in cases where you have no OS at all, no one is doing the job for you
(I know generally you don't allocate and reallocate memory on embedded systems,
but there are cases where you may want to.)
So speaking in general plain C (as which the OP is tagged),
this is simply producing erroneous and non portable code.
I typically free every allocated block once I'm sure that I'm done with it. Today, my program's entry point might be main(int argc, char *argv[]) , but tomorrow it might be foo_entry_point(char **args, struct foo *f) and typed as a function pointer.
So, if that happens, I now have a leak.
Regarding your second question, if my program took input like a=5, I would allocate space for a, or re-allocate the same space on a subsequent a="foo". This would remain allocated until:
The user typed 'unset a'
My cleanup function was entered, either servicing a signal or the user typed 'quit'
I can not think of any modern OS that does not reclaim memory after a process exits. Then again, free() is cheap, why not clean up? As others have said, tools like valgrind are great for spotting leaks that you really do need to worry about. Even though the blocks you example would be labeled as 'still reachable' , its just extra noise in the output when you're trying to ensure you have no leaks.
Another myth is "If its in main(), I don't have to free it", this is incorrect. Consider the following:
char *t;
for (i=0; i < 255; i++) {
t = strdup(foo->name);
let_strtok_eat_away_at(t);
}
If that came prior to forking / daemonizing (and in theory running forever), your program has just leaked an undetermined size of t 255 times.
A good, well written program should always clean up after itself. Free all memory, flush all files, close all descriptors, unlink all temporary files, etc. This cleanup function should be reached upon normal termination, or upon receiving various kinds of fatal signals, unless you want to leave some files laying around so you can detect a crash and resume.
Really, be kind to the poor soul who has to maintain your stuff when you move on to other things .. hand it to them 'valgrind clean' :)
It is completely fine to leave memory unfreed when you exit; malloc() allocates the memory from the memory area called "the heap", and the complete heap of a process is freed when the process exits.
That being said, one reason why people still insist that it is good to free everything before exiting is that memory debuggers (e.g. valgrind on Linux) detect the unfreed blocks as memory leaks, and if you have also "real" memory leaks, it becomes more difficult to spot them if you also get "fake" results at the end.
This code will usually work alright, but consider the problem of code reuse.
You may have written some code snippet which doesn't free allocated memory, it is run in such a way that memory is then automatically reclaimed. Seems allright.
Then someone else copies your snippet into his project in such a way that it is executed one thousand times per second. That person now has a huge memory leak in his program. Not very good in general, usually fatal for a server application.
Code reuse is typical in enterprises. Usually the company owns all the code its employees produce and every department may reuse whatever the company owns. So by writing such "innocently-looking" code you cause potential headache to other people. This may get you fired.
What's the real result here?
Your program leaked the memory. Depending on your OS, it may have been recovered.
Most modern desktop operating systems do recover leaked memory at process termination, making it sadly common to ignore the problem (as can be seen by many other answers here.)
But you are relying on a safety feature not being part of the language, one you should not rely upon. Your code might run on a system where this behaviour does result in a "hard" memory leak, next time.
Your code might end up running in kernel mode, or on vintage / embedded operating systems which do not employ memory protection as a tradeoff. (MMUs take up die space, memory protection costs additional CPU cycles, and it is not too much to ask from a programmer to clean up after himself).
You can use and re-use memory (and other resources) any way you like, but make sure you deallocated all resources before exiting.
If you're using the memory you've allocated, then you're not doing anything wrong. It becomes a problem when you write functions (other than main) that allocate memory without freeing it, and without making it available to the rest of your program. Then your program continues running with that memory allocated to it, but no way of using it. Your program and other running programs are deprived of that memory.
Edit: It's not 100% accurate to say that other running programs are deprived of that memory. The operating system can always let them use it at the expense of swapping your program out to virtual memory (</handwaving>). The point is, though, that if your program frees memory that it isn't using then a virtual memory swap is less likely to be necessary.
There's actually a section in the OSTEP online textbook for an undergraduate course in operating systems which discusses exactly your question.
The relevant section is "Forgetting To Free Memory" in the Memory API chapter on page 6 which gives the following explanation:
In some cases, it may seem like not calling free() is reasonable. For
example, your program is short-lived, and will soon exit; in this case,
when the process dies, the OS will clean up all of its allocated pages and
thus no memory leak will take place per se. While this certainly “works”
(see the aside on page 7), it is probably a bad habit to develop, so be wary
of choosing such a strategy
This excerpt is in the context of introducing the concept of virtual memory. Basically at this point in the book, the authors explain that one of the goals of an operating system is to "virtualize memory," that is, to let every program believe that it has access to a very large memory address space.
Behind the scenes, the operating system will translate "virtual addresses" the user sees to actual addresses pointing to physical memory.
However, sharing resources such as physical memory requires the operating system to keep track of what processes are using it. So if a process terminates, then it is within the capabilities and the design goals of the operating system to reclaim the process's memory so that it can redistribute and share the memory with other processes.
EDIT: The aside mentioned in the excerpt is copied below.
ASIDE: WHY NO MEMORY IS LEAKED ONCE YOUR PROCESS EXITS
When you write a short-lived program, you might allocate some space
using malloc(). The program runs and is about to complete: is there
need to call free() a bunch of times just before exiting? While it seems
wrong not to, no memory will be "lost" in any real sense. The reason is
simple: there are really two levels of memory management in the system.
The first level of memory management is performed by the OS, which
hands out memory to processes when they run, and takes it back when
processes exit (or otherwise die). The second level of management
is within each process, for example within the heap when you call
malloc() and free(). Even if you fail to call free() (and thus leak
memory in the heap), the operating system will reclaim all the memory of
the process (including those pages for code, stack, and, as relevant here,
heap) when the program is finished running. No matter what the state
of your heap in your address space, the OS takes back all of those pages
when the process dies, thus ensuring that no memory is lost despite the
fact that you didn’t free it.
Thus, for short-lived programs, leaking memory often does not cause any
operational problems (though it may be considered poor form). When
you write a long-running server (such as a web server or database management
system, which never exit), leaked memory is a much bigger issue,
and will eventually lead to a crash when the application runs out of
memory. And of course, leaking memory is an even larger issue inside
one particular program: the operating system itself. Showing us once
again: those who write the kernel code have the toughest job of all...
from Page 7 of Memory API chapter of
Operating Systems: Three Easy Pieces
Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
Arpaci-Dusseau Books
March, 2015 (Version 0.90)
There's no real danger in not freeing your variables, but if you assign a pointer to a block of memory to a different block of memory without freeing the first block, the first block is no longer accessible but still takes up space. This is what's called a memory leak, and if you do this with regularity then your process will start to consume more and more memory, taking away system resources from other processes.
If the process is short-lived you can often get away with doing this as all allocated memory is reclaimed by the operating system when the process completes, but I would advise getting in the habit of freeing all memory you have no further use for.
You are correct, memory is automatically freed when the process exits. Some people strive not to do extensive cleanup when the process is terminated, since it will all be relinquished to the operating system. However, while your program is running you should free unused memory. If you don't, you may eventually run out or cause excessive paging if your working set gets too big.
You are absolutely correct in that respect. In small trivial programs where a variable must exist until the death of the program, there is no real benefit to deallocating the memory.
In fact, I had once been involved in a project where each execution of the program was very complex but relatively short-lived, and the decision was to just keep memory allocated and not destabilize the project by making mistakes deallocating it.
That being said, in most programs this is not really an option, or it can lead you to run out of memory.
It depends on the scope of the project that you're working on. In the context of your question, and I mean just your question, then it doesn't matter.
For a further explanation (optional), some scenarios I have noticed from this whole discussion is as follow:
(1) - If you're working in an embedded environment where you cannot rely on the main OS' to reclaim the memory for you, then you should free them since memory leaks can really crash the program if done unnoticed.
(2) - If you're working on a personal project where you won't disclose it to anyone else, then you can skip it (assuming you're using it on the main OS') or include it for "best practices" sake.
(3) - If you're working on a project and plan to have it open source, then you need to do more research into your audience and figure out if freeing the memory would be the better choice.
(4) - If you have a large library and your audience consisted of only the main OS', then you don't need to free it as their OS' will help them to do so. In the meantime, by not freeing, your libraries/program may help to make the overall performance snappier since the program does not have to close every data structure, prolonging the shutdown time (imagine a very slow excruciating wait to shut down your computer before leaving the house...)
I can go on and on specifying which course to take, but it ultimately depends on what you want to achieve with your program. Freeing memory is considered good practice in some cases and not so much in some so it ultimately depends on the specific situation you're in and asking the right questions at the right time. Good luck!
If you're developing an application from scratch, you can make some educated choices about when to call free. Your example program is fine: it allocates memory, maybe you have it work for a few seconds, and then closes, freeing all the resources it claimed.
If you're writing anything else, though -- a server/long-running application, or a library to be used by someone else, you should expect to call free on everything you malloc.
Ignoring the pragmatic side for a second, it's much safer to follow the stricter approach, and force yourself to free everything you malloc. If you're not in the habit of watching for memory leaks whenever you code, you could easily spring a few leaks. So in other words, yes -- you can get away without it; please be careful, though.
If a program forgets to free a few Megabytes before it exits the operating system will free them. But if your program runs for weeks at a time and a loop inside the program forgets to free a few bytes in each iteration you will have a mighty memory leak that will eat up all the available memory in your computer unless you reboot it on a regular basis => even small memory leaks might be bad if the program is used for a seriously big task even if it originally wasn't designed for one.
It depends on the OS environment the program is running in, as others have already noted, and for long running processes, freeing memory and avoiding even very slow leaks is important always. But if the operating system deals with stuff, as Unix has done for example since probably forever, then you don't need to free memory, nor close files (the kernel closes all open file descriptors when a process exits.)
If your program allocates a lot of memory, it may even be beneficial to exit without "hesitation". I find that when I quit Firefox, it spends several !minutes ! paging in gigabytes of memory in many processes. I guess this is due to having to call destructors on C++ objects. This is actually terrible. Some might argue, that this is necessary to save state consistently, but in my opinion, long-running interactive programs like browsers, editors and design programs, just to mention a few, should ensure that any state information, preferences, open windows/pages, documents etc is frequently written to permanent storage, to avoid loss of work in case of a crash. Then this state-saving can be performed again quickly when the user elects to quit, and when completed, the processes should just exit immediately.
All memory allocated for this process will be marked unused by OS then reused, because the memory allocation is done by user space functions.
Imagine OS is a god, and the memories is the materials for creating a wolrd of process, god use some of materials creat a world (or to say OS reserved some of memory and create a process in it). No matter what the creatures in this world have done the materials not belong to this world won't be affected. After this world expired, OS the god, can recycle materials allocated for this world.
Modern OS may have different details on releasing user space memory, but that has to be a basic duty of OS.
I think that your two examples are actually only one: the free() should occur only at the end of the process, which as you point out is useless since the process is terminating.
In you second example though, the only difference is that you allow an undefined number of malloc(), which could lead to running out of memory. The only way to handle the situation is to check the return code of malloc() and act accordingly.

what happens to malloc?

Well I think I know the answer to the question but I rather be assured. If you malloc memory on the heap and exit the program before you free the space does the os or compiler free the space for you ?
The OS free the space for you when it removes the process's descriptor (task_struct in Linux's case) from its process list.
The compiler usually generates an exit() system call and there's where all this is handled.
On Linux, basically, all these happens in the kernel's exit_mm() function, eventually invoked by exit(). It will release the address space owned by the process with mm_release() function. All that source is available for you to read (although it might get a little complicated :) But yes, the operating system is in charge of releasing process's resources.
And just because I like it so much, if you're into these topics, this is a very GOOD reading: Understanding the Linux Kernel.
That is outside the scope of the C standard. What happens depends on the system. On all common mainstream operative systems, the OS will free the memory when the process is done.
Still, it is good practice to always clean up your own mess. So no matter what the OS does, you should always free up all resources you were using. Doing so is also an excellent way to spot hidden runtime bugs: if you have bugs, the program might crash when you try to free the resources and thereby alerting the programmer of the bugs.
As for the compiler, it is only active during program creation, it has absolutely nothing to do with the runtime execution of your program.
The OS will clear all resources consumed by your program, including all allocated memory, network connections, filehandles etc.

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?.

What REALLY happens when you don't free after malloc before program termination?

We are all taught that you MUST free every pointer that is allocated. I'm a bit curious, though, about the real cost of not freeing memory. In some obvious cases, like when malloc() is called inside a loop or part of a thread execution, it's very important to free so there are no memory leaks. But consider the following two examples:
First, if I have code that's something like this:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
What's the real result here? My thinking is that the process dies and then the heap space is gone anyway so there's no harm in missing the call to free (however, I do recognize the importance of having it anyway for closure, maintainability, and good practice). Am I right in this thinking?
Second, let's say I have a program that acts a bit like a shell. Users can declare variables like aaa = 123 and those are stored in some dynamic data structure for later use. Clearly, it seems obvious that you'd use some solution that will calls some *alloc function (hashmap, linked list, something like that). For this kind of program, it doesn't make sense to ever free after calling malloc because these variables must be present at all times during the program's execution and there's no good way (that I can see) to implement this with statically allocated space. Is it bad design to have a bunch of memory that's allocated but only freed as part of the process ending? If so, what's the alternative?
Just about every modern operating system will recover all the allocated memory space after a program exits. The only exception I can think of might be something like Palm OS where the program's static storage and runtime memory are pretty much the same thing, so not freeing might cause the program to take up more storage. (I'm only speculating here.)
So generally, there's no harm in it, except the runtime cost of having more storage than you need. Certainly in the example you give, you want to keep the memory for a variable that might be used until it's cleared.
However, it's considered good style to free memory as soon as you don't need it any more, and to free anything you still have around on program exit. It's more of an exercise in knowing what memory you're using, and thinking about whether you still need it. If you don't keep track, you might have memory leaks.
On the other hand, the similar admonition to close your files on exit has a much more concrete result - if you don't, the data you wrote to them might not get flushed, or if they're a temp file, they might not get deleted when you're done. Also, database handles should have their transactions committed and then closed when you're done with them. Similarly, if you're using an object oriented language like C++ or Objective C, not freeing an object when you're done with it will mean the destructor will never get called, and any resources the class is responsible might not get cleaned up.
Yes you are right, your example doesn't do any harm (at least not on most modern operating systems). All the memory allocated by your process will be recovered by the operating system once the process exits.
Source: Allocation and GC Myths (PostScript alert!)
Allocation Myth 4: Non-garbage-collected programs
should always deallocate all memory
they allocate.
The Truth: Omitted
deallocations in frequently executed
code cause growing leaks. They are
rarely acceptable. but Programs that
retain most allocated memory until
program exit often perform better
without any intervening deallocation.
Malloc is much easier to implement if
there is no free.
In most cases, deallocating memory
just before program exit is pointless.
The OS will reclaim it anyway. Free
will touch and page in the dead
objects; the OS won't.
Consequence: Be careful with "leak
detectors" that count allocations.
Some "leaks" are good!
That said, you should really try to avoid all memory leaks!
Second question: your design is ok. If you need to store something until your application exits then its ok to do this with dynamic memory allocation. If you don't know the required size upfront, you can't use statically allocated memory.
=== What about future proofing and code reuse? ===
If you don't write the code to free the objects, then you are limiting the code to only being safe to use when you can depend on the memory being free'd by the process being closed ... i.e. small one-time use projects or "throw-away"[1] projects)... where you know when the process will end.
If you do write the code that free()s all your dynamically allocated memory, then you are future proofing the code and letting others use it in a larger project.
[1] regarding "throw-away" projects. Code used in "Throw-away" projects has a way of not being thrown away. Next thing you know ten years have passed and your "throw-away" code is still being used).
I heard a story about some guy who wrote some code just for fun to make his hardware work better. He said "just a hobby, won't be big and professional". Years later lots of people are using his "hobby" code.
You are correct, no harm is done and it's faster to just exit
There are various reasons for this:
All desktop and server environments simply release the entire memory space on exit(). They are unaware of program-internal data structures such as heaps.
Almost all free() implementations do not ever return memory to the operating system anyway.
More importantly, it's a waste of time when done right before exit(). At exit, memory pages and swap space are simply released. By contrast, a series of free() calls will burn CPU time and can result in disk paging operations, cache misses, and cache evictions.
Regarding the possiblility of future code reuse justifing the certainty of pointless ops: that's a consideration but it's arguably not the Agile way. YAGNI!
I completely disagree with everyone who says OP is correct or there is no harm.
Everyone is talking about a modern and/or legacy OS's.
But what if I'm in an environment where I simply have no OS?
Where there isn't anything?
Imagine now you are using thread styled interrupts and allocate memory.
In the C standard ISO/IEC:9899 is the lifetime of memory stated as:
7.20.3 Memory management functions
1 The order and contiguity of storage allocated by successive calls to the calloc,
malloc, and realloc functions is unspecified. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated). The lifetime of an allocated object extends
from the allocation until the deallocation.[...]
So it has not to be given that the environment is doing the freeing job for you.
Otherwise it would be added to the last sentence: "Or until the program terminates."
So in other words:
Not freeing memory is not just bad practice. It produces non portable and not C conform code.
Which can at least be seen as 'correct, if the following: [...], is supported by environment'.
But in cases where you have no OS at all, no one is doing the job for you
(I know generally you don't allocate and reallocate memory on embedded systems,
but there are cases where you may want to.)
So speaking in general plain C (as which the OP is tagged),
this is simply producing erroneous and non portable code.
I typically free every allocated block once I'm sure that I'm done with it. Today, my program's entry point might be main(int argc, char *argv[]) , but tomorrow it might be foo_entry_point(char **args, struct foo *f) and typed as a function pointer.
So, if that happens, I now have a leak.
Regarding your second question, if my program took input like a=5, I would allocate space for a, or re-allocate the same space on a subsequent a="foo". This would remain allocated until:
The user typed 'unset a'
My cleanup function was entered, either servicing a signal or the user typed 'quit'
I can not think of any modern OS that does not reclaim memory after a process exits. Then again, free() is cheap, why not clean up? As others have said, tools like valgrind are great for spotting leaks that you really do need to worry about. Even though the blocks you example would be labeled as 'still reachable' , its just extra noise in the output when you're trying to ensure you have no leaks.
Another myth is "If its in main(), I don't have to free it", this is incorrect. Consider the following:
char *t;
for (i=0; i < 255; i++) {
t = strdup(foo->name);
let_strtok_eat_away_at(t);
}
If that came prior to forking / daemonizing (and in theory running forever), your program has just leaked an undetermined size of t 255 times.
A good, well written program should always clean up after itself. Free all memory, flush all files, close all descriptors, unlink all temporary files, etc. This cleanup function should be reached upon normal termination, or upon receiving various kinds of fatal signals, unless you want to leave some files laying around so you can detect a crash and resume.
Really, be kind to the poor soul who has to maintain your stuff when you move on to other things .. hand it to them 'valgrind clean' :)
It is completely fine to leave memory unfreed when you exit; malloc() allocates the memory from the memory area called "the heap", and the complete heap of a process is freed when the process exits.
That being said, one reason why people still insist that it is good to free everything before exiting is that memory debuggers (e.g. valgrind on Linux) detect the unfreed blocks as memory leaks, and if you have also "real" memory leaks, it becomes more difficult to spot them if you also get "fake" results at the end.
This code will usually work alright, but consider the problem of code reuse.
You may have written some code snippet which doesn't free allocated memory, it is run in such a way that memory is then automatically reclaimed. Seems allright.
Then someone else copies your snippet into his project in such a way that it is executed one thousand times per second. That person now has a huge memory leak in his program. Not very good in general, usually fatal for a server application.
Code reuse is typical in enterprises. Usually the company owns all the code its employees produce and every department may reuse whatever the company owns. So by writing such "innocently-looking" code you cause potential headache to other people. This may get you fired.
What's the real result here?
Your program leaked the memory. Depending on your OS, it may have been recovered.
Most modern desktop operating systems do recover leaked memory at process termination, making it sadly common to ignore the problem (as can be seen by many other answers here.)
But you are relying on a safety feature not being part of the language, one you should not rely upon. Your code might run on a system where this behaviour does result in a "hard" memory leak, next time.
Your code might end up running in kernel mode, or on vintage / embedded operating systems which do not employ memory protection as a tradeoff. (MMUs take up die space, memory protection costs additional CPU cycles, and it is not too much to ask from a programmer to clean up after himself).
You can use and re-use memory (and other resources) any way you like, but make sure you deallocated all resources before exiting.
If you're using the memory you've allocated, then you're not doing anything wrong. It becomes a problem when you write functions (other than main) that allocate memory without freeing it, and without making it available to the rest of your program. Then your program continues running with that memory allocated to it, but no way of using it. Your program and other running programs are deprived of that memory.
Edit: It's not 100% accurate to say that other running programs are deprived of that memory. The operating system can always let them use it at the expense of swapping your program out to virtual memory (</handwaving>). The point is, though, that if your program frees memory that it isn't using then a virtual memory swap is less likely to be necessary.
There's actually a section in the OSTEP online textbook for an undergraduate course in operating systems which discusses exactly your question.
The relevant section is "Forgetting To Free Memory" in the Memory API chapter on page 6 which gives the following explanation:
In some cases, it may seem like not calling free() is reasonable. For
example, your program is short-lived, and will soon exit; in this case,
when the process dies, the OS will clean up all of its allocated pages and
thus no memory leak will take place per se. While this certainly “works”
(see the aside on page 7), it is probably a bad habit to develop, so be wary
of choosing such a strategy
This excerpt is in the context of introducing the concept of virtual memory. Basically at this point in the book, the authors explain that one of the goals of an operating system is to "virtualize memory," that is, to let every program believe that it has access to a very large memory address space.
Behind the scenes, the operating system will translate "virtual addresses" the user sees to actual addresses pointing to physical memory.
However, sharing resources such as physical memory requires the operating system to keep track of what processes are using it. So if a process terminates, then it is within the capabilities and the design goals of the operating system to reclaim the process's memory so that it can redistribute and share the memory with other processes.
EDIT: The aside mentioned in the excerpt is copied below.
ASIDE: WHY NO MEMORY IS LEAKED ONCE YOUR PROCESS EXITS
When you write a short-lived program, you might allocate some space
using malloc(). The program runs and is about to complete: is there
need to call free() a bunch of times just before exiting? While it seems
wrong not to, no memory will be "lost" in any real sense. The reason is
simple: there are really two levels of memory management in the system.
The first level of memory management is performed by the OS, which
hands out memory to processes when they run, and takes it back when
processes exit (or otherwise die). The second level of management
is within each process, for example within the heap when you call
malloc() and free(). Even if you fail to call free() (and thus leak
memory in the heap), the operating system will reclaim all the memory of
the process (including those pages for code, stack, and, as relevant here,
heap) when the program is finished running. No matter what the state
of your heap in your address space, the OS takes back all of those pages
when the process dies, thus ensuring that no memory is lost despite the
fact that you didn’t free it.
Thus, for short-lived programs, leaking memory often does not cause any
operational problems (though it may be considered poor form). When
you write a long-running server (such as a web server or database management
system, which never exit), leaked memory is a much bigger issue,
and will eventually lead to a crash when the application runs out of
memory. And of course, leaking memory is an even larger issue inside
one particular program: the operating system itself. Showing us once
again: those who write the kernel code have the toughest job of all...
from Page 7 of Memory API chapter of
Operating Systems: Three Easy Pieces
Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau
Arpaci-Dusseau Books
March, 2015 (Version 0.90)
There's no real danger in not freeing your variables, but if you assign a pointer to a block of memory to a different block of memory without freeing the first block, the first block is no longer accessible but still takes up space. This is what's called a memory leak, and if you do this with regularity then your process will start to consume more and more memory, taking away system resources from other processes.
If the process is short-lived you can often get away with doing this as all allocated memory is reclaimed by the operating system when the process completes, but I would advise getting in the habit of freeing all memory you have no further use for.
You are correct, memory is automatically freed when the process exits. Some people strive not to do extensive cleanup when the process is terminated, since it will all be relinquished to the operating system. However, while your program is running you should free unused memory. If you don't, you may eventually run out or cause excessive paging if your working set gets too big.
You are absolutely correct in that respect. In small trivial programs where a variable must exist until the death of the program, there is no real benefit to deallocating the memory.
In fact, I had once been involved in a project where each execution of the program was very complex but relatively short-lived, and the decision was to just keep memory allocated and not destabilize the project by making mistakes deallocating it.
That being said, in most programs this is not really an option, or it can lead you to run out of memory.
It depends on the scope of the project that you're working on. In the context of your question, and I mean just your question, then it doesn't matter.
For a further explanation (optional), some scenarios I have noticed from this whole discussion is as follow:
(1) - If you're working in an embedded environment where you cannot rely on the main OS' to reclaim the memory for you, then you should free them since memory leaks can really crash the program if done unnoticed.
(2) - If you're working on a personal project where you won't disclose it to anyone else, then you can skip it (assuming you're using it on the main OS') or include it for "best practices" sake.
(3) - If you're working on a project and plan to have it open source, then you need to do more research into your audience and figure out if freeing the memory would be the better choice.
(4) - If you have a large library and your audience consisted of only the main OS', then you don't need to free it as their OS' will help them to do so. In the meantime, by not freeing, your libraries/program may help to make the overall performance snappier since the program does not have to close every data structure, prolonging the shutdown time (imagine a very slow excruciating wait to shut down your computer before leaving the house...)
I can go on and on specifying which course to take, but it ultimately depends on what you want to achieve with your program. Freeing memory is considered good practice in some cases and not so much in some so it ultimately depends on the specific situation you're in and asking the right questions at the right time. Good luck!
If you're developing an application from scratch, you can make some educated choices about when to call free. Your example program is fine: it allocates memory, maybe you have it work for a few seconds, and then closes, freeing all the resources it claimed.
If you're writing anything else, though -- a server/long-running application, or a library to be used by someone else, you should expect to call free on everything you malloc.
Ignoring the pragmatic side for a second, it's much safer to follow the stricter approach, and force yourself to free everything you malloc. If you're not in the habit of watching for memory leaks whenever you code, you could easily spring a few leaks. So in other words, yes -- you can get away without it; please be careful, though.
If a program forgets to free a few Megabytes before it exits the operating system will free them. But if your program runs for weeks at a time and a loop inside the program forgets to free a few bytes in each iteration you will have a mighty memory leak that will eat up all the available memory in your computer unless you reboot it on a regular basis => even small memory leaks might be bad if the program is used for a seriously big task even if it originally wasn't designed for one.
It depends on the OS environment the program is running in, as others have already noted, and for long running processes, freeing memory and avoiding even very slow leaks is important always. But if the operating system deals with stuff, as Unix has done for example since probably forever, then you don't need to free memory, nor close files (the kernel closes all open file descriptors when a process exits.)
If your program allocates a lot of memory, it may even be beneficial to exit without "hesitation". I find that when I quit Firefox, it spends several !minutes ! paging in gigabytes of memory in many processes. I guess this is due to having to call destructors on C++ objects. This is actually terrible. Some might argue, that this is necessary to save state consistently, but in my opinion, long-running interactive programs like browsers, editors and design programs, just to mention a few, should ensure that any state information, preferences, open windows/pages, documents etc is frequently written to permanent storage, to avoid loss of work in case of a crash. Then this state-saving can be performed again quickly when the user elects to quit, and when completed, the processes should just exit immediately.
All memory allocated for this process will be marked unused by OS then reused, because the memory allocation is done by user space functions.
Imagine OS is a god, and the memories is the materials for creating a wolrd of process, god use some of materials creat a world (or to say OS reserved some of memory and create a process in it). No matter what the creatures in this world have done the materials not belong to this world won't be affected. After this world expired, OS the god, can recycle materials allocated for this world.
Modern OS may have different details on releasing user space memory, but that has to be a basic duty of OS.
I think that your two examples are actually only one: the free() should occur only at the end of the process, which as you point out is useless since the process is terminating.
In you second example though, the only difference is that you allow an undefined number of malloc(), which could lead to running out of memory. The only way to handle the situation is to check the return code of malloc() and act accordingly.

Resources