The usual way is with (pseudo-code first):
node = head # start at the head.
while node != null: # traverse entire list.
temp = node # save node pointer.
node = node.next # advance to next.
free temp # free the saved one.
head = null # finally, mark as empty list.
The basic idea is to remember the node to free in a separate variable then advance to the next before freeing it.
You only need to remember one node at a time, not the entire list as you propose.
In terms of what you need to add to your code, you can, during deletion, use head
as the continuously updating list head (as it’s meant to be) and curr
to store the item you’re currently deleting:
while ((curr = head) != NULL) { // set curr to head, stop if list empty.
head = head->next; // advance head to next element.
free (curr); // delete saved pointer.
}
This is a little shorter than the pseudo-code above simply because it takes advantage of C “shorthand” for some operations.