在c中释放单链表

时间:2016-03-08 20:32:14

标签: c singly-linked-list

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

这是我的结构列表和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输出显示大小正在减小。两个printf围绕着“head = NULL;”声明都打印大小为零。这也通过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_destroy之后的printf如何仍然输出2,(特别是当printf时)在list_destroy中,传入的list_t *最后的大小为0。

1 个答案:

答案 0 :(得分:3)

  

但是当方法返回时,传递的指针仍指向一个完整列表。

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

问题有一个名称 - 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;
}