5

Here's my function to delete a linked list:

void deleteList( NODE* head )
{
    NODE* temp1; 
    NODE* tempNext;
    temp1 = head;
    tempNext = NULL;

    while( temp1 != NULL )
    {
        tempNext = temp1->next;
        free(temp1);
        temp1 = tempNext;
    }
}

So temp1 first points where the head pointer is pointing. If it isn't NULL, tempNext will be set to point to the next element of the list. Then the first element (temp1) is free'd, and temp1 is reassigned to point to where tempNext is pointing and process repeats.

Is this the right approach to deleting an entire list?

I ask this because when I print the list after using this function, it still prints the list. And IIRC freeing something doesn't delete it but only marks it as available so I'm not sure how to tell if this is correct or not.

2
  • 1
    It also depends on how your list looks like. If you've allocated memory for the data (if your list contains a pointer to data) then you might want to free that one too and just not the list that keeps a reference to it. Commented Dec 17, 2012 at 16:02
  • @Jite: Oh good point~! I'll keep that in mind for the future Commented Dec 17, 2012 at 16:05

4 Answers 4

7

Your code looks correct.

You're also correct that freeing a list's elements doesn't immediately change the memory they pointed to. It just returns the memory to the heap manager which may reallocate it in future.

If you want to make sure that client code doesn't continue to use a freed list, you could change deleteList to also NULL their NODE pointer:

void deleteList( NODE** head )
{
    NODE* temp1 = *head;
    /* your code as before */
    *head = NULL;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Just notice pointer-to-pointer as argument to the function.
1

It still print the list, because you probably don't set the head pointer to NULL after calling this function.

Comments

1

I ask this because when I print the list after using this function, it still prints the list.

There is a difference between freeing a pointer and invalidating a pointer. If you free your whole linked list and the head, it means that you no longer "own" the memory at the locations that head and all the next pointers point to. Thus you can't garintee what values will be there, or that the memory is valid.

However, the odds are pretty good that if you don't touch anything after freeing your linked list, you'll still be able to traverse it and print the values.

struct node{
    int i;
    struct node * next;
};

...
struct node * head = NULL;
head = malloc(sizeof(struct node));
head->i = 5;
head->next = NULL;
free(head);
printf("%d\n", head->i); // The odds are pretty good you'll see "5" here

You should always free your pointer, then directly set it to NULL because in the above code, while the comment is true. It's also dangerous to make any assumptions about how head will react/contain after you've called free().

Comments

0

This is a pretty old question, but maybe it'll help someone performing a search on the topic.

This is what I recently wrote to completely delete a singly-linked list. I see a lot of people who have heartburn over recursive algorithms involving large lists, for fear of running out of stack space. So here is an iterative version.

Just pass in the "head" pointer and the function takes care of the rest...

struct Node {
    int i;
    struct Node *next;

};

void DeleteList(struct Node *Head) {

    struct Node *p_ptr;

    p_ptr = Head;

    while (p_ptr->next != NULL) {
            p_ptr = p_ptr->next;
            Head->next = p_ptr->next;
            free(p_ptr);
            p_ptr = Head;
    }

    free(p_ptr);

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.