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

C++自定义Stack类使用StackItem*类指针时push方法报nullptr错误求助

报错直接根因

对空指针head执行了解引用操作。
当栈为空时IsEmpty()返回true,此时head的值为nullptr,直接执行*head = input等价于向内存地址0写入数据,属于非法内存访问,直接触发崩溃。

核心逻辑错误(链表栈实现完全不符合预期)

你当前的入栈逻辑完全偏离了链表栈的设计思路,结合老师要求head为StackItem*(指向栈顶节点的指针)的规则,问题出在这几点:

  • 传入的input是值传递的临时对象,仅存在于push函数的栈帧中,函数执行结束就会被销毁,无法作为持久的链表节点存在
  • 你试图将临时对象input直接赋值给head指向的内存,但空栈时head根本没有指向任何有效内存;非空栈时直接覆盖原栈顶节点,完全没有实现“新增节点作为新栈顶”的逻辑
  • 你没有为新入栈的节点分配独立的堆内存,链表节点必须持久存在于堆上才能跨函数调用使用
修正后的实现步骤

1. 修正Stack构造函数

必须显式将head初始化为nullptr,否则head是未初始化的野指针,会出现随机报错:

Stack::Stack() {
    head = nullptr;
}

2. 重写push方法

完全按照链表入栈逻辑实现,不需要解引用空head:

void Stack::push(StackItem input) {
    // 为新节点分配堆内存,复制传入的input值
    StackItem* newNode = new StackItem(input);
    // 新节点的next指针指向原栈顶节点
    newNode->next = head;
    // 更新head指针,指向新的栈顶节点
    head = newNode;
}

这里完全符合老师要求的head为StackItem*的规则,关联逻辑为:每个新入栈的节点自己保存下一个节点的指针,head永远指向最新的栈顶节点,不需要对head执行解引用赋值操作。

3. 修正Calculator构造函数的内存泄漏问题

你之前在Calculator里手动new了StackItem传入push,现在push内部已经会自动分配堆内存,不需要额外创建临时指针,直接传值即可:

Calculator::Calculator(string input)
{
    infixExpression = input;
    stack = new Stack();
    for (int i = 0;i < input.length();i++) {
        char c = input[i];
        std::string s(1, c);
        stack->push(StackItem(s)); // 直接构造值传入,不需要手动new
    }
}

4. 补充Stack析构函数的内存释放逻辑

因为push时在堆上分配了节点,必须在析构函数中遍历释放,否则会内存泄漏:

Stack::~Stack() {
    while (head != nullptr) {
        StackItem* temp = head;
        head = head->next;
        delete temp;
    }
}
补充说明

你之前的逻辑本质是混淆了“指针本身存的地址”和“指针指向的内存内容”的区别:head是一个指针变量,它存的是栈顶节点的地址,入栈时需要做的是修改head存的地址(让它指向新节点),而不是直接修改head指向的地址里的内容——空栈时head存的是nullptr(地址0),根本没有对应的有效内存可以修改。

内容的提问来源于stack exchange,提问作者Oğuzcan Şirolu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 09:06:04