I have a struct which you see below:
typedef struct _List {
Person *person; // pointer for people list
DoList *do; // Kinda timer, for checking list
If you have allocated an object using malloc()
, then you need to free()
it at some point.
So you asked "...any need to free...?" and the answer is "it depends."
If the struct is needed almost until the program terminates via a return from main(),
exit()
, or a signal, then no it should never be freed regardless of what is in it.1
If the resource is allocated dynamically in a long-lived process such as an editor or server daemon, but if after a transaction or period of time it is no longer needed, then yes, it does need to be freed or the program will have a memory leak.
Freeing the structure will produce a memory leak if the contained objects are also dynamically allocated. Either nothing at all should be freed or the entire graph of objects with a root at that structure will need to be freed.
The rule is simple, each individual malloc()
must correspond to a single individual free()
.
1. Saying this generally attracts a small flood of doctrinaire "you must free everything" protest, but such protest is partly misinformed. The C++ Faq discusses the issue well. One concern is that it's slow and pointless to page in or touch lots of pages that the OS is able to free as a block. But yes, there is an argument that it's a good design pattern, good practice, and if there is any possibility of incorporating the code into a second program then memory should be freed always.
void free_mystruct(struct_List *a_ptr){
free(a_ptr->person);
free(a_ptr->do);
free(a_ptr);
}
if you used malloc to initially allocate memory.
You have to free the struct if you allocated it dynamically. You have to free its members before deallocating the struct if you allocated the members dynamically and don't have a reference to them anywhere else.
Here are some examples:
void freeNotRequiredHere() {
List nonDynamicList;
Person nonDynamicPerson;
DoList nonDynamicDoList;
nonDynamicList.person = &nonDynamicPerson;
nonDynamicList.do = &nonDynamicDoList;
}
void freeRequiredForStructListOnly() {
List *dynamicList;
Person nonDynamicPerson;
DoList nonDynamicDoList;
dynamicList = (List *) malloc( sizeof(struct List) );
dynamicList->person = &nonDynamicPerson;
dynamicList->do = &nonDynamicDoList;
free( dynamicList );
}
void freeRequiredForStructListAndPersonOnly() {
List *dynamicList;
Person *dynamicPerson;
DoList nonDynamicDoList;
dynamicList = (List *) malloc( sizeof(struct List) );
dynamicPerson = (Person *) malloc( sizeof(Person) );
dynamicList->person = dynamicPerson;
dynamicList->do = &nonDynamicDoList;
free( dynamicPerson );
free( dynamicList );
}
void freeRequiredForStructListAndPersonOnly( DoList *notSureDoList ) {
List *dynamicList;
Person *dynamicPerson;
dynamicList = (List *) malloc( sizeof(struct List) );
dynamicPerson = (Person *) malloc( sizeof(Person) );
dynamicList->person = dynamicPerson;
dynamicList->do = notSureDoList;
// maybe notSureDoList was allocated with malloc(),
// maybe it is a non-dynamic stack variable.
// the calling function should deal with free()'ing notSureDoList
free( dynamicPerson );
free( dynamicList );
}