简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM