I'm implementing a linked list and it needs to have a function that when given a head of a linked list and a cstring, it finds and deletes a node whose value is the cstring.
typedef struct node
{
char entry[21];
struct node* next;
} node;
/*returns true if node with phrase value found, otherwise false*/
bool findAndRemove(node* root, char phrase[21])
{
if(root != NULL)
{
node* previous = NULL;
while(root->next != NULL)
{
if(strcmp(root->entry, phrase) == 0)//found
{
if(previous == NULL)//node to delete is at head
{
node* tmp = root;
root = root->next;
free(tmp);
return true;
}
previous->next = root->next;
free(root);
return true;
}
previous = root;
root = root->next;
}
return false;
}
}
It works alright but when deleting the head some garbage gets printed out. What is happening and how can I fix this? Do I have any memory leaks? Out of curiosity is the term "root" or "head" more commonly used for the first node in a linked list?
The first thing to realise is that removing an element from a linked list involves changing exactly one pointer value: the pointer that points at us. This can be the external
head
pointer that points to the first list element, or one of the->next
pointers inside the list. In both cases that pointer needs to be changed; its new value should become the value of the->next
pointer of the node to be deleted.In order to change some object (from within a function) we need a pointer to it. We need to change a pointer, so we will need a pointer to pointer.
The number of
if
conditions can even be reduced to one by doing the dirty work in the loop,and returning from the loop but that would be a bit of a hack:But what if the list is not unique, and we want to delete all the nodes that satisfy the condition? We just alter the loop logic a bit and add a counter:
Update: and a driver program to test it:
And the output:
You construct a list by pointing to the first node.
Then you delete the first node, but do not update the pointer to the list to point to the second one
Just make your function check if you are deleting the first node, and always return a pointer to the first pointer of the final list. Alternatively, instead of
node *root
parameter, passnode **root
so you can modifiy the reference in your function (although I don't like this way of working).You are changing the root inside the function, thus you need to pass a double pointer: