You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

这段Linked List节点新增代码出现无限迭代的原因是什么?

链表添加节点无限循环问题解决方案

核心问题根因

你的代码存在2个致命逻辑错误,直接破坏了链表结构:

  1. 空链表判断逻辑完全错误
    你写的if(r == NULL)永远不会触发:r是&(list)->nodes的取地址结果,只要list是合法指针,r不可能为NULL。你实际要判断的是*r == NULL,也就是头指针是否为空,代表链表是否为空。且如果r真的为NULL,*r = w属于空指针解引用,会直接触发段错误。
  2. 遍历过程直接修改原链表头指针
    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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 17:36:08