这段Linked List节点新增代码出现无限迭代的原因是什么?
链表添加节点无限循环问题解决方案
核心问题根因
你的代码存在2个致命逻辑错误,直接破坏了链表结构:
- 空链表判断逻辑完全错误
你写的if(r == NULL)永远不会触发:r是&(list)->nodes的取地址结果,只要list是合法指针,r不可能为NULL。你实际要判断的是*r == NULL,也就是头指针是否为空,代表链表是否为空。且如果r真的为NULL,*r = w属于空指针解引用,会直接触发段错误。 - 遍历过程直接修改原链表头指针
r是指向原链表头成员list->nodes的二级指针,循环中执行(*r) = (*r)->next相当于直接修改原链表的头指针,会丢失前面的节点,甚至意外构造出环形链表,触发while无限循环。
异常复现逻辑(为什么前两次正常、第三次崩溃)
- 第一次添加节点:链表为空,你错误的判断分支未生效,头指针赋值符合预期
- 第二次添加节点:进入循环后直接匹配到
(*r)->next == NULL的条件,赋值后直接break,没有执行到修改*r的代码行,头指针未被篡改,运行正常 - 第三次添加节点:头节点的next已经存在值,会走到
(*r) = (*r)->next的代码,直接修改原链表头指针,链表结构被破坏,后续遍历就可能出现环形链表,触发无限循环
修复代码
你可以选择用临时一级指针遍历,完全不触碰原头指针:
struct node *w = calloc(1, sizeof(struct node)); if (w == NULL) { // 自行处理内存分配失败的场景 return; } w->next = NULL; struct node **r = &(list)->nodes; // 空链表直接赋值头节点 if (*r == NULL) { *r = w; return; } // 用临时指针遍历,不修改原链表头 struct node *tmp = *r; while (tmp->next != NULL) { tmp = tmp->next; } tmp->next = w;
如果你希望用二级指针的写法遍历,也可以用临时二级指针避免修改原头:
struct node *w = calloc(1, sizeof(struct node)); if (w == NULL) { return; } w->next = NULL; struct node **curr = &(list)->nodes; while (*curr != NULL) { curr = &(*curr)->next; } *curr = w;
内容的提问来源于stack exchange,提问作者Kortik
相关产品推荐
相关产品推荐

