Search code examples
cpointersfree

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?


Solution

  • 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;
    }