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)
You allocate memory for a
int
and makeheight
point to this memory.You then you make
height
point topHeight
which is a variable with automatic storage duration. This as a result leads to a memory leak since the memory youmalloc()
'd is now lost.You then call
free()
onheight
, which is pointing to memory that isn't frommalloc()
,calloc()
orrealloc()
, so usingfree()
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 return
ed 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;