10

I have a function that takes a pointer to a char ** and fills it with strings (an array of strings I guess). *list_of_strings* is allocated memory inside the function.

char * *list_of_strings = NULL;

/* list_of_strings malloc'd inside function */
fill_strings_with_stuff(&list_of strings);

use_list_for_something(list_of_strings);

/* Now how do I free it all? */

How would I go about freeing the memory after I've used the strings? If I call

free(list_of_strings);

won't that just free the actual pointers and not the memory each string itself was using? How do I completely free the memory

Just for clarity the function looks something like this:

fill_strings_with_stuff(char *** list)
{
    *list = malloc(AMOUNT);

    for (i = 0; i < SOMETHING; i++) {
        *(list + i) = malloc(LINE_LEN);
        *(list + i) = some_string_from_somewhere
    }

    /* ... */

}
caesius
  • 101
  • 1
  • 1
  • 3
  • 3
    You've got a memory leak: `*(list + i) = some_string_from_somewhere` overwrites the pointer obtained from malloc. – sharptooth Jan 19 '11 at 09:38
  • This is a good point. You should use something like strcpy/strncpy/other alternative to copy the string. Personally I would recommend using something like snprintf if for no other reason than it forces you to evaluate your assumptions. – leeor_net Jul 19 '17 at 08:09

4 Answers4

17

won't that just free the actual pointers and not the memory each string itself was using?

Yes, indeed.

How do I completely free the memory

By looping through the array and freeing each string one by one before freeing up the array itself. E.g.

for (i = 0; i < SOMETHING; i++) {
    free(list[i]);
}
free(list);
Péter Török
  • 114,404
  • 31
  • 268
  • 329
7

Basically, there's a rule of thumb to allocating and freeing: You need to call as many free() as you called malloc(). It's as simple as that. In every other case you got yourself a memory leak.

0xCAFEBABE
  • 5,576
  • 5
  • 34
  • 59
  • Does this rule of thumb apply when initializing through say `char input[10][10];`? – J. Schmidt Sep 07 '22 at 12:21
  • Although this array does decay into pointers under certain circumstances, it is allocated on the stack, and therefore local to the function it is in. It gets cleaned up when the function ends. Remember that there is much less space on the stack than on the heap (as allocated by pointers). – 0xCAFEBABE Sep 08 '22 at 09:12
4

Yes, you have to free() every block you obtained from malloc(). You do it by traversing the array of pointers and caling free() on each element and only then freeing the array itself.

Only you know that there's a tree-like structure that could be freed recursively, that knowledge is not anywhere in the C runtime heap, so the heap manager has no idea about that and your program has to free everything itself.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
2

You need to iterate over list and call free() on every array member. Then free the array.

Daniel Gehriger
  • 7,339
  • 2
  • 34
  • 55