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

如何在C++双链表类中正确删除节点以避免进入无限循环

双向链表问题修复方案

核心致命问题(导致死循环的直接原因)

double_node类的析构函数存在严重逻辑错误:

  • 析构函数中调用delete this会触发无限递归:执行delete x删除节点时,系统会自动调用对应节点的析构函数,而析构内部的delete this会再次触发析构逻辑,无限循环调用直接导致程序卡死。
  • 析构函数中this != nullptr的判断完全无效:C++调用非静态成员函数时this指针永远不为空,且delete空指针本身是合法操作,不需要额外判断。
  • 节点没有额外申请的附属资源,不需要显式写析构函数,delete操作会自动完成节点内存的回收。

其他可引发崩溃/逻辑错误的问题

remove函数问题

  • 当链表中不存在要删除的data时,while循环结束后temp为nullptr,后续直接访问temp->data属于空指针解引用,会触发程序崩溃。
  • 删除节点时没有处理tail指针的更新逻辑:如果删除的是尾节点,原tail指针会变成悬空指针,后续操作链表会出现不可预期的错误。
  • 删除头节点后如果链表为空,没有同步重置tail指针。

初始化与append函数问题

  • 初始化时提前为head、tail申请了空节点,后续又把这两个节点当作数据节点使用,边界逻辑混乱,容易出现越界错误。
  • 缺少链表整体的析构函数,销毁链表时不会自动释放所有节点内存,是内存泄漏的核心原因。

修复后代码

#include <iostream>
#include <climits>
using namespace std;
typedef long long ll;

class double_node{
public:
    ll data;
    double_node * next;
    double_node * prev;

    double_node(){
        this->next = nullptr;
        this->prev = nullptr;
        this->data = LLONG_MIN;
    }

    double_node(ll data, double_node * next, double_node * prev){
        this->data = data;
        this->next = next;
        this->prev = prev;
    }

    // 移除错误的析构函数实现,使用默认析构即可
    ~double_node() = default;
};

class double_linked_list{
public:
    double_node * head = nullptr;
    double_node * tail = nullptr;

    double_linked_list() = default;

    // 新增链表析构函数,销毁时自动释放所有节点内存,避免内存泄漏
    ~double_linked_list() {
        double_node* cur = head;
        while (cur != nullptr) {
            double_node* next = cur->next;
            delete cur;
            cur = next;
        }
        head = nullptr;
        tail = nullptr;
    }

    void append(ll data){
        double_node* new_node = new double_node(data, nullptr, nullptr);
        if (head == nullptr) {
            head = new_node;
            tail = new_node;
            return;
        }
        tail->next = new_node;
        new_node->prev = tail;
        tail = new_node;
    }

    void remove(ll data){
        double_node * temp = head;
        while(temp != nullptr && temp->data != data){
            temp = temp->next;
        }
        // 没找到对应节点直接返回,避免空指针解引用
        if (temp == nullptr) {
            return;
        }
        // 更新前驱节点的next指针
        if (temp->prev != nullptr) {
            temp->prev->next = temp->next;
        } else {
            // 删除的是头节点,更新head
            head = temp->next;
        }
        // 更新后继节点的prev指针
        if (temp->next != nullptr) {
            temp->next->prev = temp->prev;
        } else {
            // 删除的是尾节点,更新tail
            tail = temp->prev;
        }
        // 释放节点内存
        delete temp;
    }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 20:51:03