I'm just learning about malloc() and free() in C and stumbled upon an important question which I couldn't happen to find anywhere. As an example let's take this simple code snippet:
int main(int argc, char *argv[])
{
char *test = malloc(sizeof(char) * 30);
strcpy(test, "test");
FILE *file = fopen("filename", "r");
if (file == NULL){
error("Couldn't open file");
}
free(test);
...
}
How does malloc()
and free()
now work with this error which just calls exit(EXIT_FAILURE)
. Because the code doesn't reach free(test)
Are there problems if an error occurs and the String test isn't freed? Or does it free automatically when the programm exits?
CodePudding user response:
The answer to this question is that it is automatically freed.
The reason for this is that for C on Linux, memory is always tracked in two separate ways.
- Each program keeps track of what memory it has allocated, and how large each allocation is. This is malloc-level tracking.
- The operating system keeps track of which pieces of memory belong to which program. This is page-level tracking.
In other words, if a program fails to free a piece of memory, then the operating system still knows that that piece of memory belongs to that program. The memory can be freed when the program exits.
So, if the operating system can allocate memory to a program, and free it, why does malloc-level tracking even exist? When Linux allocates memory to a program, it can only do so in 4KB chunks called "pages." If you wanted to allocate 10 bytes to hold a string, it would be very wasteful to allocate a full page, and only use the first 10 bytes. For this reason, malloc() requests memory from the operating system1 in 4KB pages, and cuts them into smaller pieces if you ask for a smaller piece. Then, it keeps track of each allocation.
If you forget to free a piece of memory, and your program exits, it does not matter, because the operating system will free the memory anyway. It's still wise to free memory in error paths, because someday you might want to change the program so that it recovers from the error instead of immediately exiting.
1 I'm glossing over some details here.