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
相关产品推荐
相关产品推荐

