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

内部含QueueNode结构体的Queue类实例化即触发段错误求助

解决循环链表实现队列时的段错误问题

嘿,我一眼就揪出你触发段错误的原因了——你在构造函数里直接解引用了空指针!

咱们看这段出问题的构造函数代码:

Queue::Queue() {
    head = nullptr;
    head->prev = head;
    head->next = head;
}

你刚把head设成nullptr,紧接着就去访问head->prev和head->next。nullptr意味着没有指向任何有效内存,直接解引用它必然触发段错误,操作系统会立刻终止你的程序,这是C++里新手常踩的经典坑。

对于循环链表实现的队列,空队列的正确初始化方式有两种,这里推荐用**哑节点(哨兵节点)**方案,它能帮你避开一大堆边界条件判断,代码更健壮:

修正后的完整代码

queue.hpp

#ifndef queue_hpp
#define queue_hpp
class Queue {
    struct QueueNode {
        QueueNode *next;
        QueueNode *prev;
        int val;
        // 用初始化列表让构造更简洁
        QueueNode(int valueOne) : val(valueOne), next(nullptr), prev(nullptr) {}
    };
    QueueNode *head; // 这里head作为哑节点,始终存在,空队列时它的prev/next都指向自己
public:
    Queue();
    ~Queue();
    // 后续可以添加入队、出队、判空等方法
};
#endif

实现文件

#include "queue.hpp"
#include <iostream>

Queue::Queue() {
    // 创建哑节点,值可以随便设(不会被业务逻辑使用)
    head = new QueueNode(-1);
    // 让哑节点的prev和next都指向自己,形成循环结构
    head->prev = head;
    head->next = head;
}

Queue::~Queue() {
    // 遍历释放所有有效节点,最后释放哑节点
    QueueNode* current = head->next;
    while (current != head) {
        QueueNode* temp = current;
        current = current->next;
        delete temp;
    }
    delete head;
}

主函数

#include "queue.hpp"
#include <iostream>
using std::endl;
using std::cout;
int main() {
    Queue firstQueue;
    cout << "Queue is created!" << endl;
    return 0;
}

为什么这样改?

用哑节点的好处特别明显:

  • 空队列时不用处理head为nullptr的特殊情况,所有入队、出队操作都能复用统一逻辑
  • 入队只需要在哑节点的prev位置插入新节点,出队只需要移除哑节点的next节点,逻辑清晰不易出错
  • 析构函数通过判断current != head就能遍历所有有效节点,不会遗漏内存释放

现在再运行代码,就不会触发段错误啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:41:49