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

C语言双向链表调用del_node删除尾节点触发Segmentation Fault问题

问题分析

触发段错误的核心原因是仅释放了尾节点内存,但未维护双向链表的结构指针:

  • 调用del_node(list.tail)后,list.tail仍指向已被释放的内存(野指针)
  • 若删除的不是唯一节点,原尾节点的前一个节点next指针仍指向失效内存,遍历链表时会访问非法地址
  • 若删除的是链表最后一个节点,list.head也会变成野指针,后续操作必然触发段错误
修复方案

必须先更新链表的结构指针,再调用del_node释放节点内存,以下两种方案任选其一:

方案1:新增专门的删除尾节点函数

添加维护链表结构的函数,复用现有del_node:

/** 删除双向链表的尾节点 */
void delete_tail(DLL_t *list)
{
    if (!list->tail) { // 空链表直接返回
        printf("list is empty, nothing to delete\n");
        return;
    }

    student_t *old_tail = list->tail;

    if (list->head == list->tail) { // 链表仅一个节点
        list->head = list->tail = NULL;
    } else { // 链表有多个节点
        list->tail = old_tail->prev; // 更新tail为前一个节点
        list->tail->next = NULL;     // 新尾节点的next置空
    }

    del_node(old_tail); // 释放旧尾节点内存
}

修改switch的case 2分支:

case 2:
    delete_tail(&list);
    break;

方案2:直接在case分支中完善逻辑

若不想新增函数,可直接修改case 2的代码:

case 2:
    if (!list.tail) {
        printf("list is empty, nothing to delete\n");
        break;
    }
    student_t *old_tail = list.tail;
    if (list.head == list.tail) {
        list.head = list.tail = NULL;
    } else {
        list.tail = old_tail->prev;
        list.tail->next = NULL;
    }
    del_node(old_tail);
    break;
关键注意事项
  • 必须先判断链表是否为空,避免对NULL指针操作
  • 处理唯一节点时,要同时将head和tail置为NULL
  • 严格遵循「保存旧节点→更新链表指针→释放旧节点」的顺序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:41:19