Search code examples
cpointersstructfree

Why do I get an "invalid pointer" when freeing a pointer to a struct in C


I have just been trying to relearn structs in C, so I made this test code. In it, I have been able to successfully create a pointer to a struct in C. The code works just fine without the two free statements at the end.

However, when I add the free statements at the end of the code, I get an error of having an invalid pointer. I thought I correctly allocated the memory for the pointer to a struct as well as freeing it. I also only deallocated everything that was a pointer.

I will get an output: (last 2 lines are added only when the free statements are included in the code)

5
5 10 0x7ffc7ee52e04 20
55 40 0x7ffc7ee52e08 2000
free(): invalid pointer
Aborted (core dumped)

How do I fix this and why? (This is my first stack overflow post ever, so sorry if there is anything I did wrong or if anything is not clear)

Thank you!

Code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main() {
        struct point_struct {
                int length;
                int width;
                int *height;
        };

        struct point_struct house;  // Ignore house struct, everything here worked fine.

        house.length = 5;
        printf("%i\n", house.length);    
        house.width = 10;
        int var = 20;
        house.height = &var;
        printf("%i %i %p %i\n", house.length, house.width, house.height, *house.height);



        struct point_struct *plane = NULL;  // Declare plane pointer to struct

        plane = malloc(sizeof(struct point_struct));   // Allocate memory for pointer to plane struct
        if (plane == NULL) {
                printf("MEMORY ALLOCATION FAILED plane\n");
                exit(1);
        }


        int pLength = 55;  // Values to be stored in plane
        int pWidth = 40;
        int pHeight = 2000;

        (*plane).length = 55;   // Both (*). and -> dereference AND
        plane->width = 40;      // get an element of a struct
        int pValue = 2000;      

        (*plane).height = malloc(sizeof(int));    // Allocates memory for height in pointer to plane struct
        if ((*plane).height == NULL) {
                free(plane);
                printf("ALLOCATE MEMORY FAILURE, plane->length\n");
                exit(1);
        }
        plane->height = &pHeight;

        // prints values inside of plane including an address
        printf("%i %i %p %i\n", plane->length, plane->width, plane->height, *(plane->height));

        free(plane->height);  // Adding these 2 lines is supposed to free the struct.
        free(plane);          // However, they cause the error
 

        return 0;
}


Solution

  • int pHeight = 2000; 
    
    (*plane).height = malloc(sizeof(int)); 
    if ((*plane).height == NULL) { 
        free(plane);
        printf("ALLOCATE MEMORY FAILURE, plane->length\n");
        exit(1);
    }
    
    plane->height = &pHeight;
    
    free(plane->height)
    
    1. You allocate memory for a int and make height point to this memory.

    2. You then you make height point to pHeight which is a variable with automatic storage duration. This as a result leads to a memory leak since the memory you malloc()'d is now lost.

    3. You then call free() on height, which is pointing to memory that isn't from malloc(), calloc() or realloc(), so using free() on it is invalid.

    The free() man page says:

    void free(void *ptr);
    
    The free() function frees the memory
    space pointed to by ptr, which must
    have been returned by a previous call
    to malloc(), calloc() or realloc().