C++基于链表实现栈时push操作触发空指针运行时错误
基于链表实现栈时push操作触发空指针异常的修复方案
核心问题分析
触发head_ref was nullptr的根本原因是栈对象未被正确初始化,加上多处逻辑错误导致空指针访问。
1. initStack函数的指针传递错误
当前initStack接收Stack* s是值传递,函数内s = new Stack;仅修改了局部指针,外部传入的栈指针依然是nullptr。调用push时访问s->front自然触发空指针异常。
修复方式:
改为初始化已存在的Stack对象(需确保外部已创建Stack实例):
void initStack(Stack* s) { s->front = nullptr; // 栈空时front指向null }
如果需要函数负责分配内存,可改为返回Stack指针:
Stack* initStack() { Stack* s = new Stack; s->front = nullptr; return s; }
2. isEmpty函数逻辑完全错误
当前isEmpty判断s == NULL,这是检查栈对象是否存在,而非栈内是否有元素。正确逻辑是判断栈的链表头是否为空:
bool isEmpty(Stack* s) { return s->front == nullptr; }
3. removeFirstNode函数的多处错误
- 传递
node* head是值传递,修改head不会同步到栈的front指针,导致链表节点删除后栈的状态未更新; - 当链表只有一个节点时,
head->next是nullptr,访问head->next->data会触发空指针; - 返回
NULL不符合函数返回int的要求,应返回-1表示空栈。
修复后的removeFirstNode:
int removeFirstNode(node** head_ref) { if (*head_ref == nullptr) return -1; // 空链表返回-1 node* temp = *head_ref; int num = temp->data; // 取当前头节点的数据 *head_ref = temp->next; // 更新链表头为下一个节点 delete temp; return num; }
同时修改pop函数的调用:
int pop(Stack* s) { if (isEmpty(s)) { std::cout << "The stack is empty!"; return -1; } return removeFirstNode(&s->front); // 传递front的地址 }
4. initStack中多余的节点初始化
原代码给front新建一个data=0的节点,导致栈初始状态不为空,违背栈的逻辑。栈空时front应指向nullptr,如修正后的initStack所示。
完整修正后的关键代码片段
stack.cpp修正后
#include <iostream> #include "Stack.h" #include "LinkedList.h" void initStack(Stack* s) { s->front = nullptr; // 栈空时front为null } void cleanStack(Stack* s) { // 清理所有链表节点,避免内存泄漏 node* current = s->front; while (current != nullptr) { node* temp = current; current = current->next; delete temp; } s->front = nullptr; } void push(Stack* s, unsigned int element) { addToTop(&s->front, element); } int pop(Stack* s) { if (isEmpty(s)) { std::cout << "The stack is empty!"; return -1; } return removeFirstNode(&s->front); } bool isEmpty(Stack* s) { return s->front == nullptr; } bool isFull(Stack* s) { return false; // 链表实现的栈不会满 }
linkedlist.cpp修正后
#include "LinkedList.h" #include <iostream> void addToTop(node** head_ref, int new_data) { node* ptr = new node; ptr->data = new_data; ptr->next = *head_ref; // 统一处理空/非空链表的情况 *head_ref = ptr; } int removeFirstNode(node** head_ref) { if (*head_ref == nullptr) return -1; node* temp = *head_ref; int num = temp->data; *head_ref = temp->next; delete temp; return num; }
内容的提问来源于stack exchange,提问作者AyAm
相关产品推荐
相关产品推荐

