Bob John
Bob John

Reputation: 467

Trying to understand behavior when freeing allocated memory

I have code that functions like this:

void** array;
array = malloc(8*sizeof(void*));

And if I put, say, three elements into the array and try:

int i = 0;
for(i; i < 8; i++)
   free(array[i]);

It fails after 6 iterations of the loop. But if I populate the entire array (with 8 elements), the for loop executes just fine. I've tried this with 18 as well, and the loop fails after 9 iterations, but if I populate the whole thing it executes fine.

Can someone please explain what's happening here?

Upvotes: 0

Views: 52

Answers (2)

legends2k
legends2k

Reputation: 32904

Memory allocated for and assigned to pointer to pointer is of type pointer so as to assign further memory for the inner pointers to hold the actual data i.e int** is assigned with memory of int* so that ints can be assigned to the allocated int*:

// array is a double pointer variable
void **array = malloc(8 * sizeof *array);  // (1) allocate memory for 8 void* pointers
for (int i = 0; i < 8; ++i)
   array[i] = malloc(sizeof(int));
   // (2) - malloc for the actual data to be pointed by the above allocated pointers

then you've to do this for freeing the memory

for (int i = 0; i < 8; ++i)
   free(array[i]);                                  // undo (2)
free(array);                                        // undo (1)

You've to match every malloc with a free. Since you've done only 1, you should undo only 1.

Upvotes: 0

Wyzard
Wyzard

Reputation: 34563

The memory returned by malloc is not initialized; it may contain garbage data. You're allocating an array of pointers, but its initial contents are not valid pointers. You're setting some of the items to (presumably) valid pointers, but leaving others uninitialized, and then you call free on all the items — even the uninitialized garbage ones.

You need to either:

  • keep track of which items in the array have been set to a valid pointer, and call free only on those items, or
  • explicitly initialize all the items to NULL. This makes it safe to free them all, since free(NULL) is valid (and does nothing).

Upvotes: 3

Related Questions