包含多级指针的二叉树对象深拷贝实现析构崩溃问题咨询
问题根因
你当前的崩溃是标准的浅拷贝导致的重复释放问题:
- 现有的
vertex拷贝构造逻辑直接把原节点的leftChild/rightChild指针赋值给新节点,没有为子节点单独开辟内存,新树和原树的所有子节点都指向同一块堆内存 - 两个树生命周期结束触发析构时,同一块子节点内存会被两个树的析构函数各释放一次,直接触发内存访问错误
修复方案
第一步:为vertex类实现递归深拷贝的拷贝构造函数
替换你原来的浅拷贝逻辑,内部递归生成所有子节点的独立副本:
// vertex类中新增/替换拷贝构造函数 vertex(const vertex& other) { // 若要求拷贝后节点key和原节点完全一致,直接写key = other.key即可,不用ID++ key = ID++; data = other.data; height = other.height; parent = nullptr; // 递归深拷贝左子树 if (other.leftChild != nullptr) { leftChild = new vertex(*other.leftChild); leftChild->parent = this; // 给左孩子绑定新的父节点指针 } else { leftChild = nullptr; } // 递归深拷贝右子树 if (other.rightChild != nullptr) { rightChild = new vertex(*other.rightChild); rightChild->parent = this; // 给右孩子绑定新的父节点指针 } else { rightChild = nullptr; } }
提示:原来的
vertex(vertex* node)浅拷贝构造函数如果没有其他用途建议直接删除,避免后续误用。
第二步:修复BTree类的拷贝构造和赋值运算符
补充空树边界处理、赋值运算符自赋值防御,以及缺失的返回值:
// BTree拷贝构造,只要vertex实现了深拷贝,这里直接调用即可 BTree(const BTree& p_BTree) { if (p_BTree.root != nullptr) { root = new vertex(*p_BTree.root); } else { root = nullptr; } } // 修复后的BTree赋值运算符 BTree& operator= (const BTree& other) { // 自赋值防御:避免自己给自己赋值时误删内存 if (this == &other) { return *this; } // 释放当前树原有内存 delete root; root = nullptr; // 深拷贝目标树 if (other.root != nullptr) { root = new vertex(*other.root); } return *this; }
内容的提问来源于stack exchange,提问作者Vendor
相关产品推荐
相关产品推荐

