C 通过*headRef链接列表和删除节点

C 通过*headRef链接列表和删除节点,c,pointers,data-structures,linked-list,C,Pointers,Data Structures,Linked List,我正在处理一些指针/链表问题。其中一个问题是删除列表中的所有节点并将头部指向NULL 我的答案与给出的答案不同。我是新来的,所以我很难弄清楚我的是否和为什么不起作用。我遇到的主要问题是试图理解free(*headRef)的结果是,如果*headRef之后可以共享不同的指针对象 我的想法是:因为我有恭维指向下一个节点,所以我可以释放指向第一个节点的*headRef(或者更一般地说,一个恭维之前的节点)。然后,我可以将*headRef指向恭维,过程可以继续 这是我的密码: void DeleteLi

我正在处理一些指针/链表问题。其中一个问题是删除列表中的所有节点并将头部指向NULL

我的答案与给出的答案不同。我是新来的,所以我很难弄清楚我的是否和为什么不起作用。我遇到的主要问题是试图理解
free(*headRef)的结果
是,如果
*headRef
之后可以共享不同的指针对象

我的想法是:因为我有
恭维
指向下一个节点,所以我可以释放指向第一个节点的
*headRef
(或者更一般地说,一个恭维之前的节点)。然后,我可以将
*headRef
指向
恭维
,过程可以继续

这是我的密码:

void DeleteList(struct node** headRef){

    struct node* compliment = *headRef;

    while (compliment != NULL){
            compliment = compliment->next;
            free(*headRef);
            *headRef = compliment;
    }
    *headRef = NULL;
}

假设每个节点都带有两个属性:一个int和一个next指针。

您发布的代码很好。删除所有节点的关键步骤是确保不要尝试删除一个指针,然后跟随它的
next
指针。由于在每次迭代中使用
compaind
指针来保持下一个节点,所以您所拥有的看起来很好

对于
free(*headRef)
-这将释放
headRef
指向的指针。完成此操作后,应确保不再跟随指针
*headRef
。由于您可以立即更改下一行中的
*headRef
,以指向链接列表中的下一个节点,因此无需担心任何问题。主要的问题是不要
释放
指针,然后尝试取消引用它
free
ing指针不会以某种方式“毒害”指针变量并使其变糟;相反,它破坏了指针,使其变得糟糕

一个细节-函数的最后一行不是必需的,因为当您访问链表的最后一个节点并遍历其
next
指针时,您将得到
NULL
。这意味着循环的最终迭代将为您设置
*headRef
指向
NULL


希望这有帮助

您可以使用更少的代码:

void DeleteList(struct node **headRef){

    struct node *tmp;

    while ((tmp = *headref)){
            *headRef = tmp->next
            free(tmp);                
    }
}
说明:

  • 只有在*headref处有要删除的内容时,才能进入循环
  • 在循环内部:tmp不能为NULL,因此可以安全地取消对tmp的引用,因此
    *headref=tmp->next是有效的
  • 在循环之后,可以保证*headref==NULL

您遇到了什么问题?如果
headRef
NULL
,您就有麻烦了。
*headRef=NULL
之后,而
不是必需的。否则,看起来没问题。@DanielFischer-我假设调用方不应该将
NULL
指针传递到此函数中。我猜预期的用法是
DeleteList(&pointerToHeadOfList)
@templatetypedef-Correct。我想我本可以加入一个assert()。然而,这是一个练习,所以我承认我走了一些弯路。非常有用!我对“毒害”指针的概念嗤之以鼻——虽然离目标不远——因为我刚刚开始研究指针之类的东西,人们对这种神秘的可能性感到恐惧。我最担心的是取消分配头指针会对。。。不知什么原因。但我觉得我的系统是健全的。谢谢你的帮助。。。很好地捕捉到了设置为NULL的信息!这个循环什么时候结束?即使在空条件下,它也会无休止地循环吗?我不习惯将声明视为终止条件!我想理解这一点。不,条件中的
while((tmp=*headref)){…}
赋值是有效的循环条件;类似于eg
while(tmp)
。双括号是用来抑制警告的。对不起,我还是不明白。什么条件导致此循环终止?它似乎是无限的。
*headRef
在循环中被更改(分配),并将在下一个循环条件测试中重新测试(记住:分配也是一个表达式。C基本上是基于表达式的;分配是低级生命形式…。好吧,那么我想知道,什么是循环条件测试?如果这是一个任务,它将永远是真实的,不是吗?比如:
while((2=2)){
总是正确的。我想我看不出修改
*headRef
有什么关系,因为tmp将在
中重新分配,而(())