Reputation: 101
Another C question:
let's say I have a struct that has a pointer member of char*
type.
When I want to initialize an instance of the struct I call malloc
:
MyStruct* ptr = (MyStruct*)malloc(sizeof(MyStruct)
And then allocate 256 bytes of memory for the char*
member:
ptr->mem = (char*)malloc(sizeof(char)*256);
what happens to the pointer member and the memory it points to when I call
free(ptr);
?
when I check the program with valgrind I see that I have a memory leak, but when I explicitly call free(ptr->member);
I still have a memory leak and valgrind shows an "Invalid free" error
What's the proper way the manage the memory pointed by the member?
Upvotes: 1
Views: 1424
Reputation: 10819
As soon as you call free(ptr)
, none of the members in ptr
are valid any more. You can't do anything with them. But the memory that was pointed to be ptr->mem
still needs to be freed. So you must either free(ptr->mem)
first, or have otherwise copied that pointer somewhere so have a valid pointer to free.
The general pattern of allocating and freeing compound structures is something like (and it is helpful to wrap them up in nice clean functions that do this):
MyStruct* MakeMyStruct() {
MyStruct* ptr = malloc(sizeof(MyStruct)); //N.B. don't need cast if it's C
ptr->mem = malloc(sizeof(char)*256);
//initialise other members
return ptr;
}
void DestroyMyStruct(MyStruct *ptr) {
//Free members first, then the struct
free(ptr->mem);
free(ptr);
}
If some of the members are complicated structs themselves, they would in turn be allocated/freed with MakeWhatever
and DestroyWhatever
instead of malloc
and free
in the above two functions.
Upvotes: 3
Reputation: 9608
You have to free ptr->member first, then the struct
free(ptr->member);
free(ptr);
Upvotes: 3
Reputation: 272497
The rule of thumb is that you need one free
for every (successful) call to malloc
(and generally, these occur in the reverse order).
If you only free(ptr)
, then you have a memory leak (because there's no way to access the memory allocated for ptr->mem
). If you only free(ptr->mem)
, then you haven't cleared up completely (not quite as bad as a memory leak).
Upvotes: 2