含父指针的六叉树内存释放异常问题求助
解决六叉树内存释放问题
咱们先揪出你内存释放函数里的核心问题:你额外调用了delete leaf->prev;,这会直接导致重复释放父节点内存,甚至在父节点还没处理完所有子节点时就被提前删除,触发内存访问错误或者程序崩溃。
问题根源拆解
- 每个节点的
prev是指向父节点的引用,父节点的删除应该由它自己的递归调用负责。比如子节点执行delete leaf->prev时,父节点可能还在循环处理其他子节点,这会让父节点内存被提前释放,后续访问父节点的其他子节点就会碰到野指针问题。 - 根节点的
prev是NULL,delete NULL本身是安全的,但其他非根节点的prev都是有效父节点指针,重复删除同一内存地址会触发未定义行为。
修正后的内存释放函数
只需要删掉delete leaf->prev;这一行,让每个节点只负责自己的子节点删除,父节点的释放交给上层递归处理:
void destroy_tree(node *leaf) { if(leaf != NULL) { // 先递归遍历删除所有子节点 for(int i=0; i<6; i++) { destroy_tree(leaf->p[i]); } // 最后删除当前节点 delete leaf; } }
额外优化建议
- 用构造函数简化节点初始化
给node结构体加个构造函数,避免手动逐个赋值的繁琐,也减少初始化错误:
struct node { float value; int wins; int games; int visited; int colour; node *prev; node *p[6]; // 构造函数自动初始化成员 node(int col) : value(0.0), wins(0), games(0), visited(0), colour(col), prev(NULL) { memset(p, 0, sizeof(p)); // 把所有子节点指针置为NULL } };
这样根节点初始化可以简化成:
node* root = new node(c); // c是根节点的颜色
扩展函数创建子节点也更简洁:
node *child = new node(leaf->colour == 1 ? -1 : 1); child->prev = leaf; leaf->p[column] = child;
- 用智能指针彻底告别手动内存管理(C++11+)
如果你的项目支持C++11或更高版本,推荐用std::unique_ptr管理节点内存,完全不用写销毁函数,自动递归释放所有内存:
#include <memory> struct node { float value = 0.0; int wins = 0; int games = 0; int visited = 0; int colour; node* prev = nullptr; std::unique_ptr<node> p[6] = {}; // 子节点用unique_ptr自动管理 node(int col) : colour(col) {} };
当根节点的unique_ptr被销毁时,会自动递归销毁所有子节点,彻底避免内存泄漏和重复释放问题。
内容的提问来源于stack exchange,提问作者John Meighan
相关产品推荐
相关产品推荐

