vianna77
vianna77

Reputation: 505

Function to free pointers not working

I'm learning C and trying to figure out an elegant way to free my pointers at the end of the execution.

After hours debugging and experimenting different things with the following code, I couldn't manage to figure out what I was doing wrong:

int ClosePointers(char *pointersToClose[], int arraySize) {
    int index;
    for(index = 0; index < arraySize; index++) {
        char *pointer = pointersToClose[index];
        free(pointer);
    }
    return (0);
}

int main(int argc, char *argv[]) {
  char *pointersToClose[4];
  char *pointer1;
  char *pointer2;
  char *pointer3;
  char *pointer4;

  pointersToClose[0] = pointer1;
  pointersToClose[1] = pointer2;
  pointersToClose[2] = pointer3;
  pointersToClose[3] = pointer4;

  pointer1 = malloc(10);
  pointer2 = malloc(10);
  pointer3 = malloc(10);
  pointer4 = malloc(10);

  /*some important code here using the pointers*/

  ClosePointers(pointersToClose, 4);

  return 0;
}

I'm getting the following error: * glibc detected * /home/workspace/Debug/Test-POC: free(): invalid pointer: 0x00000038ce7b9850 ***

Could you help me out pointing what I'm doing wrong?

Upvotes: 3

Views: 229

Answers (4)

Vaggelis Spi
Vaggelis Spi

Reputation: 164

In order to free a pointer you must first have allocate memmory for it. You are going to free pointers that are never allocated. Try the following code to understnd what you did wrong

int AllocatePointers(char *pointersToClose[], int arraySize) {
  int index;
  for(index = 0; index < arraySize; index++) {
     pointersToClose[index] = malloc(50*sizeof(char));
  }
  return (0);
}

int main(int argc, char *argv[]) {
  char *pointersToClose[4];
  char *pointer1;
  char *pointer2;
  char *pointer3;
  char *pointer4;

  pointersToClose[0] = pointer1;
  pointersToClose[1] = pointer2;
  pointersToClose[2] = pointer3;
  pointersToClose[3] = pointer4;

  AllocatePointers(pointersToClose, 4);

  /*some important code here using the pointers*/

  ClosePointers(pointersToClose, 4);

  return 0;
}

Upvotes: 0

zmo
zmo

Reputation: 24812

Could you help me out pointing what I'm doing wrong?

You should use free() only on pointers that you allocated on the heap using the malloc() function.

What happens, is that within the heap (a reserved memory space), the length you gave as parameter to the malloc() function is allocated for your use, and it returns the address to the first word of that memory space so it can be assigned to a pointer.

When you use free(), it's deallocating that memory space so it can be reused.

Here, you create pointers variables that points to nothing (actually they point to a random value). So what's happening when you call free() on those variables is that you try to deallocate some random memory space that is not within the managed space, called the heap. As those addresses are unlikely to be allocated by malloc(), the free() function cannot know what to do with it, and therefore will return an error!

Read on about what are the stack and the heap to better understand what those are. Also, read the C programming language book by Kernighan and Ritchie where it's all well explained.

Upvotes: 1

Sourav Ghosh
Sourav Ghosh

Reputation: 134336

In your code. pointer1 is unitialized. It points to invalid memory. Passing that to free() invokes undefined behavior.

Quoting C11, chapter §7.22.3.3, (emphasis mine)

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.

You need to either

  • set that to NULL (null-pointer constant)
  • use malloc() or family to allocate free-able memory first.

That said, pointer2, pointer3 and pointer4 are undeclared in your code but probably that's a typo, so we can overlook it.

Upvotes: 0

dbush
dbush

Reputation: 223937

You're calling free on those pointers, but you never allocate any memory to them with malloc. In fact, the pointers you are trying to free are uninitialized, so they could contain anything.

When you set the values of pointersToClose, you're assigning the current value of pointer1, pointer2, etc., not whatever value they may contain when "some important code here using the pointers" runs.

Passing a pointer value to free that was not returned by malloc/realloc/calloc results in undefined behavior.

If you want to do this, try putting the address of each of the pointers in question in your array.

int ClosePointers(char **pointersToClose[], int arraySize) {
    int index;
    for(index = 0; index < arraySize; index++) {
        char **pointer = pointersToClose[index];
        free(*pointer);
    }
    return (0);
}

int main(int argc, char *argv[]) {
  char **pointersToClose[4];
  char *pointer1;
  char *pointer2;
  char *pointer3;
  char *pointer4;

  pointersToClose[0] = &pointer1;
  pointersToClose[1] = &pointer2;
  pointersToClose[2] = &pointer3;
  pointersToClose[3] = &pointer4;

  /*some important code here using the pointers*/

  ClosePointers(pointersToClose, 4);

  return 0;
}

Upvotes: 2

Related Questions