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

C++ 重载双向链表-=运算符实现差集触发段错误问题求助

问题原因分析
  • 核心错误1:-=运算符遍历链表删除节点后访问野指针
    你在嵌套循环里匹配到节点直接调用removeByNode(temp1)删除temp1,但后续循环仍然执行temp1 = temp1->get_next(),此时temp1已经被释放属于野指针,访问直接触发段错误。
  • 核心错误2:removeByNode未处理边界节点
    该函数没有判断要删除的节点是头节点/尾节点的场景:如果删除头节点,current->get_prev()返回NULL,调用NULL->set_next()直接段错误;删除尾节点同理current->get_next()返回NULL,调用NULL->set_prev()也会崩溃。
  • 衍生错误:removeFromHead、removeFromTail逻辑存在空指针风险
    这两个函数先访问head->get_next()/tail->get_prev()再判断head/tail是否为空,空链表调用时会直接访问空指针触发崩溃,且删除最后一个节点后没有同步置空头尾指针。
修复方案

1. 修复removeByNode函数

void LinkedList::removeByNode(Node* c)
{
    if (c == NULL) return; // 空指针直接返回
    // 处理前驱节点
    if (c->get_prev() != NULL) {
        c->get_prev()->set_next(c->get_next());
    } else {
        // 要删的是头节点,更新头指针
        head = c->get_next();
    }
    // 处理后继节点
    if (c->get_next() != NULL) {
        c->get_next()->set_prev(c->get_prev());
    } else {
        // 要删的是尾节点,更新尾指针
        tail = c->get_prev();
    }
    delete c;
    current = head;
}

2. 修复-=运算符逻辑

删除节点前先暂存下一个节点的地址,避免访问野指针:

LinkedList LinkedList::operator -= (const LinkedList& LL2) 
{
    Node* temp2;
    // 遍历LL2的所有元素
    for (temp2 = LL2.head; temp2 != NULL; temp2 = temp2->get_next()) 
    {
        Node* temp1 = head;
        // 遍历当前链表匹配元素
        while (temp1 != NULL) 
        {
            Node* next_node = temp1->get_next(); // 先存下一个节点
            if (temp1->get_data() == temp2->get_data()) 
            {
                removeByNode(temp1);
            }
            temp1 = next_node; // 用暂存的地址移动指针
        }
    }
    return *this;
}

3. 可选修复:完善removeFromHead、removeFromTail逻辑

void LinkedList::removeFromHead() 
{
    if (head == NULL) return; // 空链表直接返回
    Node* temp = head->get_next();
    delete head;
    head = temp;
    if (head == NULL) {
        tail = NULL; // 删完为空,同步置空尾指针
    } else {
        head->set_prev(NULL);
    }
}

void LinkedList::removeFromTail() 
{
    if (tail == NULL) return; // 空链表直接返回
    Node* temp = tail->get_prev();
    delete tail;
    tail = temp;
    if (tail == NULL) {
        head = NULL; // 删完为空,同步置空头指针
    } else {
        tail->set_next(NULL);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 07:36:03