如何正确释放链表的所有元素?

How to correctly free all elements of a linked list?

我有一个结构 table,它有点像链表。我的目标是清空 table 中的任何内容。我认为我的想法是正确的,但它不起作用,我不知道为什么。

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

我正在尝试的是获取 table 中的每一件事并对其应用 free()。然后将 table 的顶部设置为 NULL 这样我以后就无法通过它并将大小设置为 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;
}

显然这不起作用,我不知道原因。我尝试了一个简单的 运行,它甚至没有改变大小。

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

我在这里测试它 tab 是指向 table 的指针。

输出为:

table has 5 elements
table has 5 elements

你的想法是对的,但是执行起来是错误的。在您的循环中,您正在释放 cur,然后 然后 查看它的 ->next。这是未定义的行为,因为 cur 刚刚被释放。

如果要释放整个列表,则必须保留另一个临时指针以记住 cur,并且只有在前进到列表中的下一个元素后才释放它。您将无法使用 for 循环执行此操作,因为 cur = cur->next 操作不能是最后一个操作,但必须在 free().

之前完成

这是一个例子:

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;
}