Can';t从单个链表的最后一个剩余节点删除数据

Can';t从单个链表的最后一个剩余节点删除数据,c,linked-list,free,C,Linked List,Free,我试图用下面的代码删除C中单个链表的所有节点 void free_all(struct cd *head){ struct cd *tmp;

我试图用下面的代码删除C中单个链表的所有节点

void free_all(struct cd *head){                                                 
    struct cd *tmp;                                                                                                                                            
    tmp = head->next;                                                           
    while(tmp != NULL){                                                         
        head->next = tmp->next;                                                 
        free(tmp);                                                              
        tmp = head->next;                                                       
    }                                                                           
    free(head->next);                                                           
    free(head);                                                                 
    head=NULL;                                                                  
}          

但是如果我在那之后打印链表的所有元素以检查列表是否为空,那么“head”元素总是被打印出来。因此,看起来head元素没有被正确删除。怎么了?

'head'是一个函数参数,具有局部作用域。因此,尽管您在函数末尾将其设置为NULL,但这不会产生任何效果,因为函数会立即返回,将该变量移出范围

无论传入的变量是什么,都将仍然指向列表的开头(尽管该内存已被释放,但它可能仍然包含合理的数据)

头部已被释放。它只是看起来不一定是这样,因为你已经保留了一个指向它曾经所在的内存的指针

要解决此问题,只需在调用此函数释放列表后将指针设为空即可

free_all(actual_head);
actual_head = NULL;

您可以传入指向指针的指针,以便在函数中使指针为NULL,但在这种情况下,这似乎过于复杂。

'head'是一个函数参数,具有局部作用域。因此,尽管您在函数末尾将其设置为NULL,但这不会产生任何效果,因为函数会立即返回,将该变量移出范围

无论传入的变量是什么,都将仍然指向列表的开头(尽管该内存已被释放,但它可能仍然包含合理的数据)

头部已被释放。它只是看起来不一定是这样,因为你已经保留了一个指向它曾经所在的内存的指针

要解决此问题,只需在调用此函数释放列表后将指针设为空即可

free_all(actual_head);
actual_head = NULL;

您可以传入指向指针的指针,以便在函数中使指针为空,但在这种情况下,这似乎过于复杂。

为什么变量仍然指向列表的开头?我对我的答案做了一些扩展,试图回答这个问题,但基本上因为你没有改变这个变量,你只是改变了它的一个本地副本。一旦函数返回,本地副本就消失了,原始副本仍然保留。好了,现在我明白你的意思了,它可以工作了。但正如我所知,head是一个指针,所以它是“通过引用调用”,这意味着只有一个对函数的引用,并且没有本地副本,或者我错了吗?你是通过指针传递的。head结构尚未被复制,但当您将指向它的指针传递到函数中时,该指针将被复制到局部变量中。如果你想引用指针本身,你需要另一个间接层次。好了,现在我明白了。谢谢为什么变量仍然位于列表的顶部?我对我的答案做了一些扩展,试图回答这个问题,但基本上因为你没有改变这个变量,你只是改变了它的一个本地副本。一旦函数返回,本地副本就消失了,原始副本仍然保留。好了,现在我明白你的意思了,它可以工作了。但正如我所知,head是一个指针,所以它是“通过引用调用”,这意味着只有一个对函数的引用,并且没有本地副本,或者我错了吗?你是通过指针传递的。head结构尚未被复制,但当您将指向它的指针传递到函数中时,该指针将被复制到局部变量中。如果你想引用指针本身,你需要另一个间接层次。好了,现在我明白了。谢谢