使用指针与类时出现段错误,求调试通用树栈实现代码
帮你调试栈实现通用树的代码问题
我来帮你定位代码里的问题,你的代码出现段错误和循环异常,主要是两个核心错误导致的:
1. 空指针解引用触发段错误
你的Node类里,children是一个vector<Node>*类型的指针,并且默认初始化为nullptr。当你执行到第二次循环(处理值为5的节点后,要处理值为4的节点)时,会执行s.top().children->push_back(temp)——这时候s.top()是刚才创建的5节点,它的children指针还是空的,直接解引用空指针就会触发段错误,这就是你程序崩溃的直接原因。
2. 存储对象副本导致逻辑失效
你在栈里存储的是Node对象的副本,而不是指针或引用。这意味着:
- 当你把
temppush到栈里时,栈里的是一个全新的拷贝,和原来的temp不是同一个对象 - 你给
root赋值root=temp时,root也是temp的一个拷贝,和栈里的节点没有任何关联 - 后续对栈顶节点的修改,只会修改栈里的副本,不会影响实际的父节点,树的结构根本无法正确建立
修正后的代码
我调整了代码结构,解决了上述问题,同时让逻辑更清晰:
#include <iostream> #include <vector> #include <stack> using namespace std; class Node { public: int data; vector<Node*> children; // 改为直接存储节点指针的vector,默认初始化空容器,避免空指针问题 // 构造函数,初始化节点数据 Node(int val) : data(val) {} }; // 可选:递归释放树的内存,避免内存泄漏 void deleteTree(Node* node) { if (!node) return; for (auto child : node->children) { deleteTree(child); } delete node; } int main() { int a[]={10,5,4,-1,1,-1,-1,6,-1}; int n=sizeof(a)/sizeof(a[0]); stack<Node*> s; // 栈存储节点指针,操作原对象而非副本 Node* root = nullptr; for(int i=0;i<n;i++) { if(a[i]==-1) { s.pop(); } else { Node* temp = new Node(a[i]); // 创建新节点,用指针管理 if(s.empty()) { root = temp; // 根节点直接指向新创建的节点 } else { // 栈顶节点是当前节点的父节点,直接添加到它的children列表 s.top()->children.push_back(temp); } s.push(temp); // 将当前节点指针压入栈 } } // 这里可以添加树的遍历代码验证结构,比如前序遍历 // 用完后记得释放内存 deleteTree(root); return 0; }
关键修改说明
- 重构Node类:把
children从指针类型改为vector<Node*>,默认会初始化一个空的vector,彻底避免空指针解引用的问题。同时添加构造函数,更规范地初始化节点数据。 - 栈存储指针:栈里存储
Node*而非Node对象,这样我们操作的是实际的节点对象,修改父节点的children列表时,会直接作用在真实的父节点上,树的结构能正确建立。 - 内存管理:添加了
deleteTree函数递归释放内存,避免内存泄漏(这在C++里是很重要的好习惯)。
这样修改后,你的代码就能正常运行,正确构建出预期的通用树结构了。
内容的提问来源于stack exchange,提问作者Dhanyaa Bharadwaj
相关产品推荐
相关产品推荐

