C++将函数内局部节点赋值给Tree类root指针是否会产生悬空指针?
问题根因
你遇到的问题由两个明显错误导致:
- 调用
worker函数时参数传递错误:worker的形参是Tree*类型,你在main中直接传入Tree对象t,语法不匹配,会直接编译报错 - 你将栈变量
rootFound的地址赋值给Tree::root:栈变量会在函数执行结束后自动被系统回收,此时Tree::root指向的是已被释放的非法内存,后续访问属于未定义行为,出现空指针、乱码、程序崩溃都属于正常现象
解决方案
所有Node节点(包括根节点、每个Node的left/right子节点)都必须分配到堆上,不能使用栈内存存储节点实体:
- worker函数中构建二叉树时,所有节点统一使用
new分配堆内存,函数退出后堆内存不会被自动回收,指针指向的内容会一直有效 - 给Tree类添加析构函数,递归释放所有节点内存,避免内存泄漏
修正后的代码示例
class Node { public: int val; Node* left = nullptr; Node* right = nullptr; Node(int v) : val(v) {} }; class Tree{ public: Node *root; Tree(){ root = nullptr; } // 析构函数:递归释放所有节点 ~Tree() { destroyNode(root); } private: void destroyNode(Node* node) { if (node == nullptr) return; // 先释放子树,再释放当前节点 destroyNode(node->left); destroyNode(node->right); delete node; } }; void worker(Tree *t){ // 示例:构建一个简单的二叉树,所有节点都用new分配堆内存 Node* rootFound = new Node(1); rootFound->left = new Node(2); rootFound->right = new Node(3); // 赋值给Tree的root指针 t->root = rootFound; } int main(){ Tree t{}; worker(&t); // 正确传入Tree对象的地址 // 此时t.root指向的堆内存有效,可以正常访问 return 0; }
额外说明
- 所有子节点的
left/right指针只要是指向堆上分配的Node对象,就不会出现内存地址丢失的问题 - 上述实现中Tree对象离开作用域时,会自动调用析构函数释放整棵树的所有节点内存,不需要手动额外处理
内容的提问来源于stack exchange,提问作者Josh W
相关产品推荐
相关产品推荐

