释放c中的单向链表

Freeing a singly linked list in c

我在实现单向链表时遇到了一个奇怪的问题。我调用 list_destroyer 并将指针传递给列表的头部,但是当方法 returns 时,传递的指针仍然指向完整列表。我不相信我在任何地方都传递了结构。

这是我的结构列表,typedef

typedef struct list list_t
struct list{
    void* datum;
    list_t* next;
};

这是导致问题的代码

void list_destroy(list_t *head){
    list_t *destroy = head;
    while(head){
        //printf("%d \n", list_size(head));
        head = head->next;
        free(destroy);
        destroy = head;
    }
    //printf("%d \n", list_size(head));
    head = NULL;
    //printf("%d \n", list_size(head));
}

list_size 函数已被注释掉,因为它们不是必需的,但我使用它们来查看代码的输出。 printf 输出显示大小正在减小。 "head = NULL;" 语句周围的两个 printf 都打印出大小为零。 gdb也证实了这一点。但是,当我有此代码(以下)调用 list_destroy 时,传递的指针未更改。

int main(){
    list_t *test = NULL;
    int a = 1;
    int b = 2;
    list_append(test,&a);
    list_append(test,&b);
    printf("%d \n", list_size(test));
    list_destroy(test);
    printf("%d \n", list_size(test));
}

我仍然得到 list_destroy 上方和下方的 printf 到两个输出 2。我没有在任何地方初始化一个新的 list_t,所以我看不到 list_t 之后的 printf 如何=26=] 仍然会输出 2,(尤其是当 list_destroy 中的 printf 表示传入的 list_t* 最后的大小为 0 时。

however when the method returns, the pointer that is passed still points to a full list.

这是不正确的:当函数 returns 时,指针指向曾经是完整列表的内容。很有可能,您的系统会让您不间断地遍历整个列表。但是,在调用后取消引用此指针是 未定义的行为,因此相同的代码可能会在其他系统上崩溃。

这个问题有一个名字 - head 变成了一个 悬空指针

解决问题很简单 - 将指针传递给指针,完成后将其设置为 NULL

void list_destroy(list_t **headPtr){
    list_t *head = *headPtr;
    list_t *destroy = head;
    while(head){
        head = head->next;
        free(destroy);
        destroy = head;
    }
    *headPtr = NULL;
}