繁体   English   中英

在c中释放单链表

[英]Freeing a singly linked list in c

在实现单链表时,我遇到了一个似乎很奇怪的问题。 我调用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,(特别是当list_destroy中的printf时)说传入的list_t *最后的大小为0。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM