Reputation: 23
I can't figure out why my linked list has a memory leak.
I have a method called insertAtFront()
void insertAtFront(Node **head, char *key) {
Node *new = malloc(sizeof(Node));
if (!new) fatal("Malloc of new Node failed");
new->word = key;
new->next = *head;
*head = new;
}
Then I have a removeAtFront()
method that frees the node.
void removeAtFront(Node **head) {
Node *newhead = (*head)->next;
free(*head);
*head = newhead;
}
If I only add one node and then remove it, there is no leak. If I remove more than one node, valgrind shows a leak proportional to how many additional nodes were added. I really can't understand why this happens as the node is freed. Any ideas?
Upvotes: 0
Views: 867
Reputation: 144550
Your problem seems to be a life cycle issue. You did not post the calling code and a complete verifiable example. The nodes are correctly freed, but there is something that is not. Is the key
argument allocated and not freed elsewhere?
You do not free
the word
member when you free a node. If the key
argument was allocated by the function that called insertAtFront()
, it should be free'd with the node. If the word
field is allocated only some of the times, it is difficult to determine when to free it.
A good solution is for insertAtFont()
to always duplicate the key
string and for removeAtFront()
to always free the word
member:
void insertAtFront(Node **head, const char *key) {
Node *new = malloc(sizeof(*new));
if (!new) fatal("Malloc of new Node failed");
new->word = strdup(key);
if (!new->word) fatal("Malloc of Node key failed");
new->next = *head;
*head = new;
}
void removeAtFront(Node **head) {
Node *node = *head;
if (node) {
*head = node->next;
free(node->word);
free(node);
}
}
Note that it could be convenient for insertAtFront()
to return a pointer to the newly inserted node at no cost.
Upvotes: 3