I receive errors when calling free on allocated memory chunks. Based on my code, I derived the following MWE:
(Note, that free is commented out. If it is called, the error will occur.)
#include <stdio.h>
#include <malloc.h>
typedef struct foo1 {
double v1;
double v2;
double v3;
} foo1;
typedef struct foo2 {
foo1* myfoo1s;
int num_foo1;
} foo2;
void init_and_set_v1(foo2** myfoo2, int a_num){
*myfoo2 = malloc(sizeof(foo2));
(*myfoo2)->num_foo1 = a_num;
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
for(int i = 0; i < (*myfoo2)->num_foo1; i ++){
(*myfoo2)->myfoo1s[i].v1 = 1.0;
}
//free( (*myfoo2) -> myfoo1s); //location 1
}
void set_v2_and_v3(foo2* myfoo2){
for(int i = 0; i < myfoo2->num_foo1; i ++){
myfoo2->myfoo1s[i].v2 = 2.0;
myfoo2->myfoo1s[i].v3 = 3.0;
}
//free(myfoo2->myfoo1s); //location 2
}
int main(){
foo2* myfoo2;
init_and_set_v1(&myfoo2, 10);
set_v2_and_v3(myfoo2);
printf("%d\n", myfoo2->num_foo1);
// ... do other things
//free(myfoo2->myfoo1s); //location 3
printf("done.");
return 0;
}
I have a struct foo2, which contains a pointer to an array of structs foo1. I allocate memory and initialize variables using different functions, because in my use case, I need to parse different data files. I don't want to have a single huge block of code.
However, when I call free, I receive an error. I use GCC 7.5.0. I would appreciate some help as to what might be causing this.
P.S. In my original program the error is dependent from where free is called. In this MWE, it is not.
Thanks a lot.
You're allocating the wrong amount of memory:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
You want to create an array of foo1
, but you're allocating space for an array of foo2
by using sizeof(foo2)
here. Since foo2
is smaller than foo1
, you write past the end of allocated memory triggering undefined behavior
Change this to:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo1) );
And don't call free
until after you've finishing using it, in this case "location 3" is where you want to free both myfoo2->myfoo1s
and myfoo2
.