I have the following piece of code. I want to properly free all my memory. As you can see, I have a b_struct within an a_struct. I wonder whether I need to manually free the b_struct within the a_struct, and if so, what is the proper way to do it?
#include <stdlib.h>
#include <stdio.h>
struct b_struct {
int c;
};
struct a_struct {
struct b_struct b;
};
int main(int argc, char **argv)
{
struct a_struct *a;
a = calloc(1, sizeof(*a));
a->b.c = 5;
printf("Value: %d", a->b.c);
free(a);
}
I wonder whether I need to manually free the b_struct within the a_struct
No.
From the malloc(3) man page:
The
free()function frees the memory space pointed to byptr, which must have been returned by a previous call tomalloc(),calloc(), orrealloc().
When you allocated sizeof(struct a_struct) bytes, that includes all members of that structure, including the struct b_struct member. This struct member is no different than an int or char[] member; it's all just one contiguous block of memory to the allocator.
No. Not only do you not need to, you are not allowed to. The memory used in b is a part of the memory used in a; you need to free the latter as a single unit, and that includes all of the memory for b.
In general, your program should call free exactly once for each call to malloc or calloc. This doesn’t mean the number of lines of code calling free needs to be the same as the number of lines calling allocation functions; it means that each time you run the program, each call to free should be paired with exactly one call to an allocation function, and vice versa, with limited exceptions:
NULL), you don’t need to call free on NULL.free on NULL as many times as you want, although you usually don’t want.malloc, calloc, and free you might miss something.If you fail to free memory which was allocated, you have a memory leak. Your program will use more and more memory until the OS can’t give it any more, at which point it will probably crash.
If you free memory which was not allocated by one of the standard allocation functions, or free the same memory twice, it gets even worse: this is immediately undefined behavior (UB) and might do anything*. This is the type of bug you would introduce by trying to free b; the memory in question was not the actual pointer returned by calloc, and even if it were it would have already been freed as part of a.
* People often say UB might do anything a lot, but in practice you can often predict what will happen on a real system; it won’t make your computer explode unless you actually have a USB bomb plugged into the computer in question. However, I would classify invalid frees as one of the less-tame types of UB: the errors it introduces can in practice appear later than the actual bug, cause seemingly unrelated issues, and be unstable between multiple runs of the program (meaning things might look fine when you test but fail when you try to use the program, and be hard to debug). With many other forms of UB this is allowed but not as likely in practice to happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With