无法执行C函数list2set去除链表重复项,程序陷入无限循环,求排查修正
链表去重函数无限循环问题排查与修复
问题诊断
- 内层循环终止条件错误:原代码内层循环以
dup->next作为终止判断,这会跳过链表的最后一个节点(当dup是最后一个节点时,dup->next为NULL,循环直接退出),同时当dup指向无效节点时,访问dup->next会触发未定义行为。 - 删除节点后未更新
dup指针:调用deleteptr删除dup指向的节点后,该节点已被从链表中移除(可能已被释放),但原代码未更新dup的指向,导致下一次循环时dup仍指向无效内存,要么程序崩溃,要么因为dup始终不移动,循环条件持续满足,陷入无限循环。
修正方案
需要做两处核心调整:
- 内层循环的终止条件改为检查
dup是否为NULL,确保遍历p之后的所有节点。 - 删除节点前提前保存
dup的下一个节点,删除后让dup指向该节点,避免指针失效或循环停滞。
修正后的代码:
list_t * list2set(list_t *h) { list_t *p, *dup, *next_node; if (h) { for (p = h; p; p = p->next) { for (dup = p->next; dup;) { next_node = dup->next; // 提前保存下一个节点,避免删除后指针失效 if (p->given == dup->given) { h = deleteptr(h, dup); // 删除重复节点 } dup = next_node; // 无论是否删除,都推进到下一个节点 } } } return h; }
补充说明
这里假设deleteptr函数的作用是从链表中移除指定节点dup,并返回更新后的链表头指针。提前保存next_node是关键:因为删除dup节点后,dup本身的内存可能被释放,此时再访问dup->next会导致未定义行为,必须在删除操作前获取下一个节点的地址。
内容的提问来源于stack exchange,提问作者Rajat Bhushan
相关产品推荐
相关产品推荐

