Chris Costa
Chris Costa

Reputation: 691

How to correctly free all elements of a linked list?

I have a structure table which is kind of like a linked list. My goal is to empty whatever is in that table. I think my idea is correct, but it's not working and I do not know why.

typedef struct table{
    LIST *top;
    int size;
}TABLE;

What I am trying is to take every single thing in the table and apply free() to it. And then to set the top of the table to NULL so I cannot go through it later and also set the size to 0.

void empty_table(TABLE *table) {
    LIST *cur;
    for (cur = table->top; cur != NULL; cur = cur->next) {
        if (cur == NULL) return;
        free(cur);
    }
    table->top = NULL;
    table->size = 0;
}

Apparently this is not working and I don't know the reason. I tried a simple run and it doesn't even change the size.

    // ...
    printf("table has %d elements\n",tab->size);
    empty_table(tab);
    printf("table has %d elements\n",tab->size);
    // ...

Here I am testing it where tab is a pointer to table.

The output is:

table has 5 elements
table has 5 elements

Upvotes: 4

Views: 226

Answers (1)

Marco Bonelli
Marco Bonelli

Reputation: 69276

Your idea is right, but the implementation is wrong. In your loop, you are freeing cur, and then looking at its ->next. This is undefined behavior because cur was just freed.

If you want to free your entire list, you will have to keep another temporary pointer to remember cur, and free that only after you advance to the next element in the list. You will not be able to do this with a for loop, as the cur = cur->next operation cannot be the last one, but must be done before free().

Here's an example:

void empty_table(TABLE *table) {
    LIST *cur = table->top;
    LIST *tmp;

    while (cur != NULL) {
       tmp = cur;
       cur = cur->next;
       free(tmp);
    }

    table->top = NULL;
    table->size = 0;
}

Upvotes: 2

Related Questions