-4

I am having trouble understanding when to free a pointer to a pointer. For arrays, I understand that something like:

char **mat = (char**) malloc(sizeof(char*) * 100);

for(int i = 0; i < 500; i++)
    mat[i] = (char*) malloc(sizeof(char) * 50);

Would require

  1. Freeing each ith member of the mat variable, followed by a final free call to its root (the mat**). This intuitively make sense because each malloc gets a free.

However, when I do something like so:

char *str = (char *) malloc(100 * sizeof(char));
char **pstr = &str;

free(pstr);

I find this tells me I'm attempting to free an invalid pointer. My logic is if pstr is a pointer to a pointer to a malloc'd character array - freeing pstr should free str. Instead, I get an invalid pointer. What gives?

2 Answers2

5
char *str = (char *) malloc(100 * sizeof(char));
char **pstr = &str;

free(pstr); //WRONG

This is wrong. pstr is the address of some automatic variable (so is likely to sit on the call stack, not in the heap). It was not obtained by malloc, so free-ing it is forbidden (undefined behavior, i.e. UB). Be scared of UB.

Pointers are values. You can only free a pointer (actually the memory block it points to) which was previously obtained (indirectly perhaps) by malloc or calloc (and these can fail: you forgot to handle failure of malloc).

Consider defining some Matrix abstract data type. See also this.

Be aware that conventions are very important when coding in C. You need to define, document and follow your own conventions (regarding who is responsible of free-ing stuff and how that should be done - perhaps with destructor-like functions). So studying the source code of existing free software (e.g. on github) should be inspirational.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • "address of some automatic variable". This is what I needed to realize. I had too many pointer concepts moving around in my head. Thanks. – user9874031 May 31 '18 at 05:31
1

The allocated memory is pointed by *pstr so you have to free(*pstr).

Joël Hecht
  • 1,766
  • 1
  • 17
  • 18