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

C语言单链表删除指定值节点时尾节点触发double free错误求解

问题成因

你遇到的double free报错核心是代码未处理待删除节点为头节点的边界场景,且该场景刚好发生在你删除尾节点的测试用例中:

  • 代码中前驱指针pr和遍历指针cur的初始值都为头节点head,当待删除节点就是头节点时,你直接free(cur)后仍然返回指向已释放内存的原head指针,形成野指针
  • 当你删除尾节点触发报错时,对应的测试用例大概率是链表只有一个节点(头节点同时是尾节点),后续调用者对返回的野指针做遍历、释放等操作时,就会触发释放后使用(UAF),甚至重复释放同一内存块,和你贴的报错信息完全吻合
  • 非头节点的删除逻辑(包括非头的尾节点删除)本身没有问题,这也是你观察到待删除节点不是尾节点时运行正常的原因
修复方案

修改点说明

  1. 单独处理头节点匹配的边界情况,删除头节点后直接返回更新后的新头节点
  2. 非头节点的删除逻辑可以简化,无需单独判断是否为尾节点:尾节点的next本身就是NULL,直接赋值给前驱节点的next即可
  3. 调用方需要用原头指针接收函数返回值,避免头节点删除后仍持有野指针

修复后代码

node *delete(node* head, int value)
{
    // 处理空链表边界
    if (head == NULL) {
        return NULL;
    }
    // 处理头节点匹配的情况
    if (head->val == value) {
        node *temp = head;
        head = head->next;
        free(temp);
        return head;
    }
    // 遍历处理非头节点
    node *pr = head;
    for (node *cur = head->next; cur != NULL; cur = cur->next) {
        if (cur->val == value) {
            pr->next = cur->next;
            free(cur);
            return head;
        }
        pr = cur;
    }
    // 未找到匹配节点直接返回原头节点
    return head;
}

调用示例

// 正确写法,用原头指针接收返回值
head = delete(head, 5);

内容的提问来源于stack exchange,提问作者faelex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:54:04