Reputation: 5849
I have a simple Linked List node as follows
typedef struct node {
void *data;
struct ListElement *next;
} node;
Also I have a node create and delete function as follows:
void createNode(void *data){
node *n = malloc(sizeof(node));
//assign data to data and initialize pointer to NULL
}
void deleteNode(List *list, Node *node){
//Take care of the next pointer
free(node);
}
When I free the node, do I have to delete the members of the struct (data and next pointer) as well? Since I am not using malloc specifically for the members, but only for the entire struct? If so then how do I do it? Will all the members of the node be placed on the heap, and the stack will not be used at all?
Upvotes: 0
Views: 225
Reputation: 154876
data
is not a variable, it's a member of struct node
. If you dynamically allocate struct node
with a call to malloc()
, you get a chunk of memory large enough to hold all the members of the struct. This obviously includes the storage for the data
pointer, but not for the contents the pointer points to. Consequently, the storage for struct members must not be freed separately, it is enough to free
the struct.
However, since data
is itself a pointer, there is no telling where the memory it points to and whether this memory needs to be freed until we see how it is initialized.
Upvotes: 1
Reputation:
The ultimate rule: you free()
exactly the same number of times you malloc()
(or calloc()
, or...)
So:
I. If the data
points to something allocated by these functions, then yes, you need to do so.
II. node->next
is to be freed of course (assuming you are freeing the entire list), so you need to free it anyway, but only after you have taken care of the next element.
An iterative solution:
void free_list(Node *list)
{
while (list != NULL) {
Node *p = list->next;
// maybe:
// free(list->data);
free(list);
list = p;
}
}
A recursive solution:
void free_list(Node *list)
{
if (list->next != NULL) {
free_list(list->next);
}
// free(list->data);
free(list);
}
Upvotes: 2
Reputation: 183858
Usually, you will need to also free
the data
member, and you have to do that before free
ing node
,
free(node->data);
free(node);
but you don't need to free
node->next
, since either you want to keep the remainder of the list, or you free
the entire list, and then freeing the next is done in the next iteration of the loop.
You must not free node->data
if that doesn't point to allocated (with malloc
or the like) memory, but that is a rare situation.
Upvotes: 1