You need to enable JavaScript to run this app. C++链表删除单节点时误删整个列表且析构报访问越界问题
优惠活动
大模型
产品
解决方案
定价
更多

C++链表删除单节点时误删整个列表且析构报访问越界问题

问题根因分析

你的代码存在两个核心错误,直接导致了访问违例和链表结构损坏:

  • 指针操作逻辑完全错误
    处理头节点时你写了*scans = currentScan->getNext();,这里scans是Scan*类型的头指针,你需要修改的是指针本身的指向,而不是指针指向的对象内容。你当前的写法是把第一个节点的属性覆盖为第二个节点的属性,并没有修改scans的指向,delete currentScan后scans直接指向已释放的内存,变成野指针,析构遍历链表时必然触发访问违例。
    循环中*previousScan = currentScan也是同样的错误,你是要移动previousScan指针到currentScan的位置,不是把previousScan指向的对象赋值为currentScan指向的对象,这会直接破坏链表节点的原有属性。
  • Scan类的赋值运算符重载不符合规范
    C++标准拷贝赋值运算符的签名应为Scan& operator=(const Scan& scan);,你实现的是接收指针参数的重载,完全不符合常规拷贝赋值场景,且你错误的解引用赋值操作会调用这个错误的重载,直接浅拷贝next指针,进一步加剧链表结构的混乱。
修正后的代码

修正removeScan函数

bool ScanList::removeScan(int serialNumber)
{// post: IF serialNumber is present in the list 
 // THEN scan has been removed from it and true has been returned 
 // ELSE false has been returned 
    Scan* currentScan = scans;
    Scan* previousScan = nullptr;

    if (currentScan != NULL && currentScan->getSerialNumber() == serialNumber)
    { // 修改头指针本身的指向,不要解引用
        scans = currentScan->getNext();
        delete currentScan;
        return true;
    }

    while (currentScan != NULL && currentScan->getSerialNumber() != serialNumber)
    {
        // 移动previousScan指针,不要解引用
        previousScan = currentScan;
        currentScan = currentScan->getNext();
    }

    if (currentScan == NULL)
    { 
        return false;
    }

    previousScan->setNext(currentScan->getNext());
    delete currentScan;
    return true;
}

修正Scan类拷贝赋值运算符

Scan& Scan::operator=(const Scan& scan)
{
    if (this == &scan)
    { 
        return *this;
    }
    this->serialNumber = scan.serialNumber;
    this->timesRecycled = scan.timesRecycled;
    // 单个节点赋值不要直接拷贝next指针,避免破坏链表结构,有深拷贝需求时单独处理节点链表
    this->next = nullptr;
    return *this;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 12:21:04