C++使用指针为n叉树节点赋值时vector存储值被覆盖问题
问题原因
- 核心问题是局部栈对象的生命周期问题:你在for循环内部定义的
Node subNode是栈上分配的临时对象,每轮for循环结束后该对象就会被系统自动回收,你存入subNodes的指针全部都是指向已经/即将失效的内存地址,属于野指针。 - 此外,每轮循环中系统大概率会给
subNode分配同一块栈内存地址,所以你存入vector的所有指针最终都指向同一块内存区域,后续循环对该内存的赋值自然会覆盖之前的值,这就是你看到subNodes[0]->value持续变化的原因。你此前将指针置为空的操作没有解决根本问题,因为后续你仍然把指针指向了临时栈对象的地址。
修复方案
推荐使用堆内存分配节点,手动控制节点的生命周期,修改后的可运行代码如下:
#include <string.h> #include <vector> #include <iostream> using namespace std; struct Node{ vector<Node*> subNodes; bool isFile=0; bool isDir=0; int value=0; }; int main() { Node rootNode; Node* rootNode_ptr = &rootNode; rootNode_ptr->value=99; for(int i=0;i<5;i++){ // 堆上分配节点,生命周期由自己控制,不会随循环结束自动销毁 Node* subNode_ptr = new Node(); subNode_ptr->value=i; rootNode_ptr->subNodes.push_back(subNode_ptr); cout<<"0 : "<<rootNode_ptr->subNodes[0]->value<<endl; cout<<rootNode_ptr->subNodes[i]->value<<endl; } // 程序结束前释放堆内存,避免内存泄漏 for(auto p : rootNode_ptr->subNodes) { delete p; } rootNode_ptr->subNodes.clear(); return 0; }
修改后运行时subNodes[0]->value会固定为0,不会再被后续赋值覆盖。
如果不想手动管理内存,也可以将vector<Node*>改为vector<Node>直接存储节点对象,避免野指针问题,仅需要注意大节点场景下的拷贝开销即可。
内容的提问来源于stack exchange,提问作者Fisherman_Zhu
相关产品推荐
相关产品推荐

