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

删除双向链表尾元素触发signal SIGSEGV segmentation fault的原因是什么

问题定位
  • 核心问题1:put函数头插新元素时,未修改原有首节点的prev指针指向新节点,导致除首节点外所有元素的prev指针始终为nullptr。当执行get操作从尾部删除元素时,dl.last->prev取到空值,后续操作访问dl.last->next触发空指针解引用段错误。
  • 次要问题2:get函数中声明buffer指针时执行了不必要的new操作,会产生内存泄漏:new申请的内存地址会被后续buffer = dl.last赋值覆盖,永远无法被释放。
解决方案
  1. 修正put函数逻辑,头插新元素后,若原有链表非空,将原首节点的prev指向新的首节点
  2. 移除get函数中buffer指针对应的无用new操作,直接用指针指向待删除节点即可
修正后的完整dlist.h代码
#include <iostream>
#include <exception>

struct DListElem {          // 链表元素
    int info;
    DListElem * prev;
    DListElem * next;
};

struct DList{               // 存储链表首尾元素指针
    DListElem * first;
    DListElem * last;
};

void initializeDList(DList & dl){  // 将dl初始化为空链表
    dl.first = nullptr;
    dl.last = nullptr;
}

void put(DList& dl, int val){  // 在链表头部插入值为val的新元素
    DListElem* front_elem = new DListElem;
    front_elem->info = val;
    front_elem->prev = nullptr;
    front_elem->next = dl.first;
    // 新增逻辑:原有首节点非空时,prev指向新首节点
    if (dl.first != nullptr) {
        dl.first->prev = front_elem;
    }
    dl.first = front_elem;
            
    if(dl.last==nullptr) dl.last=dl.first;
}

bool get(DList& dl, int& val){
    /* 从链表尾部删除元素(可操作时),删除元素的值通过val参数返回,释放链表元素内存。返回值表示是否成功取出元素,空链表返回false,否则返回true。*/
    if(dl.last==nullptr) return false;
    DListElem* buffer = dl.last; // 直接指向待删除节点,无需new
    val = dl.last->info;
    if (dl.first==dl.last){             // 链表仅有1个元素
        dl.last = nullptr;
        dl.first = nullptr; 
    }
    else{
        dl.last = dl.last->prev;
        dl.last->next = nullptr;
    }
    delete buffer;
    return true;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 23:15:03