1

In my beginning programs in C, I noticed I call free a lot, so I thought of making a call-once function that frees up everything. Is this code a valid way of doing it, or are there any other suggestions to improve it?

#include <stdio.h>
#include <stdlib.h>

void *items_to_free[1024];
int intItemsToFree = 0;

void mm_init(void)
{
    int i;

    for (i = 0; i < 1024; i++)
    {
        items_to_free[i] = NULL;
    }
}

void mm_release(void)
{
    int i;

    for (i = 0; i < 1024; i++)
    {
        if (items_to_free[i])
        {
            printf("Freeing %p\n", items_to_free[i]);
            free(items_to_free[i]);
            items_to_free[i] = NULL;
        }    
    }
}

void mm_add(void *p)
{
    items_to_free[intItemsToFree++] = p;
}


int main(void)
{
    int *i = NULL;

    /* initialize memory management */
    mm_init();

    /* allocate something */
    i = (int *) malloc(sizeof(int) * 10);

    /* add it to the memory collection */
    mm_add(i);

    /* run program as usual */
    printf("App doing something...");

    /* at the end, free all memory */
    mm_release();

    return 0;
} 

Output:

App doing something...Freeing 0x100103b30
10
  • 1
    If you really wanted to do this, why not write a wrapper on malloc that'll automatically call mm_add? Commented Dec 11, 2013 at 17:37
  • 1
    You could create a function which calls malloc and adds the returned pointer to items_to_free before returning that to the called Commented Dec 11, 2013 at 17:38
  • 1
    This question belongs on CodeReview. Not StackOverflow. Commented Dec 11, 2013 at 17:38
  • How is making use of this much easier than calling free() when you use malloc()? You still have to add a function call (mm_add()) for each malloc in the above case. Commented Dec 11, 2013 at 17:38
  • 1
    OMG this is a terrible idea. PRETTY PLEASE DO NOT EVER DO THIS!!! Commented Dec 11, 2013 at 17:39

1 Answer 1

7

While for a simple application this may seem like a good idea, in reality it's not. Let's consider two cases:

1) mm_release is called at program termination

This means that mm_release is completely useless and is a waste of time. Any OS since decades ago would clean that memory up for you in one big gulp. Doing it yourself piece by piece is just a waste of time.

2) mm_release is called somewhere in between

This means that mm_release has to be specialized. You release memory during execution because you are done with some memory and you want to give it back so it could be used somewhere else in your program. mm_release would have to be given exact information on what should be released and what not. This is exactly what free does.


So as you can see, mm_release is really not helping you at all. In the first case, it's useless and you can simply get rid of it. In the second case, you are better off directly using free since you are selectively freeing memory anyway.

Note also that your method is very thread-unfriendly.


You may think that mm_release could group the allocated memory in related sets, where you can free all memories in a set with one call. While this may look attractive, it's again quite useless in reality. First of all, in reality either you don't have many memory allocations that are semantically similar so they can be grouped, or if you do, then they are already put together in an array or equivalent.

So either the memory sets have single elements (which means you don't gain anything by using this method), or you are simply avoiding a for loop at the cost of an unnecessarily complicated library.


Last but not least, memory is a resource in the same system just as many others. You open files one by one and close them one by one. You get semaphores one by one and you release them one by one. You open pipes one by one and you close them one by one. Heck, you even open { one by one and close it with } one by one. It doesn't make sense to make an exception for memory.

In fact, some people who were very afraid of memory tried your method in the past. They called it garbage collector and it's an insult to regularity in resource management. (Those same people were also very afraid of pointers and basically programming in general)

Sign up to request clarification or add additional context in comments.

16 Comments

So... free() is unnecessary these days, unless specifically manipulating memory?
@phil, think about it like this: Imagine you are playing Starcraft. Obviously, every time you start a new game, the game loads (i.e. allocates memory) the map and its objects. Think of the disaster if it forgets to free that memory once the game is finished. You can play a couple of rounds until your memory is used-up and the game is forced to close itself.
@phil, that's kind of correct. First of all, .NET is object oriented. In C++, this means that on object destruction (for example the destruction of a vector locally allocated on stack which is automatic) it manages to free it's own memory. In garbage languages (I mean garbage collecting languages) such as Java and C#, there is another process behind the scene that performs memory deallocation.
All of this will help prevent my users from hunting me down. Thanks for the help.
@MartinJames, feel free to award 90 bounty ;)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.