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

Time:09-26

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

CodePudding user response:

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().

CodePudding user response:

When you call free(plane->height), it's pointing at the local variable pHeight. You're only permitted to call free with a pointer that was returned via something in the malloc family.

CodePudding user response:

You allocated dynamically memory for an object of the type int

(*plane).height = malloc(sizeof(int));    // Allocates memory for height in pointer to plane struct

But then you reassigned the value of the pointer

plane->height = &pHeight;

that now points to the local variable pHeight

int pHeight = 2000;

So the code produces a memory leak because the address of the dynamically allocated memory is lost. And you may not call the function free for a pointer that points to a local variable.

Instead you should write

*plane->height = pHeight;
  • Related