C++二叉搜索树拷贝构造函数出现段错误问题求助
二叉搜索树拷贝构造函数段错误的原因与修复方案
嘿,我一眼就瞅出你这段代码的问题啦——你在copy_helper里修改的指针根本没传递回外部的root!最终root还是个未初始化的野指针,访问它可不就触发段错误了嘛。
先看看你的原代码片段:
template <typename T> BTree<T>::BTree(const BTree<T>& other) { copy_helper(this->root, other.root); } template <typename T> void BTree<T>::copy_helper(Node<T>* copy_to, const Node<T>* copy_from) const { if(copy_from == NULL){ copy_to = NULL; } else{ copy_to = new Node<T>; copy_to->value = copy_from->value; // 推测你这里是要复制节点值 // 递归复制左右子树(你代码里没写完,但逻辑应该是这样) copy_helper(copy_to->left, copy_from->left); copy_helper(copy_to->right, copy_from->right); } }
核心问题:指针的传值调用坑了你
你给copy_helper的第一个参数是Node<T>* copy_to,这是传值调用——也就是说,函数里的copy_to是this->root的一个副本。你在函数里给copy_to赋值new Node<T>或者NULL,只会修改这个副本,外部的this->root完全没变化,还是原来的垃圾值。后续访问这个野指针,必然会触发段错误。
两种修复方案
方案一:使用指针的引用作为参数
把copy_helper的第一个参数改成指针的引用,这样函数里的修改会直接作用到原指针上:
template <typename T> void BTree<T>::copy_helper(Node<T>*& copy_to, const Node<T>* copy_from) const { if(copy_from == nullptr){ // 推荐用C++11的nullptr代替NULL,更规范 copy_to = nullptr; } else{ copy_to = new Node<T>(copy_from->value); // 直接用构造函数初始化更优雅 copy_helper(copy_to->left, copy_from->left); copy_helper(copy_to->right, copy_from->right); } }
现在调用copy_helper(this->root, other.root)时,copy_to就是this->root的别名,函数里的赋值会直接修改this->root,递归复制左右子树也能正确设置节点的左右指针。
方案二:让copy_helper返回新节点指针
另一种更简洁的写法是让copy_helper返回构建好的节点指针,然后在拷贝构造函数里直接赋值给this->root:
template <typename T> BTree<T>::BTree(const BTree<T>& other) { root = copy_helper(other.root); } template <typename T> Node<T>* BTree<T>::copy_helper(const Node<T>* copy_from) const { if(copy_from == nullptr){ return nullptr; } else{ Node<T>* new_node = new Node<T>(copy_from->value); new_node->left = copy_helper(copy_from->left); new_node->right = copy_helper(copy_from->right); return new_node; } }
这种逻辑更直观:每个递归调用返回当前节点的拷贝,然后把左右子树的拷贝赋值给新节点的左右指针,最后把整棵树的根节点赋值给this->root。
额外提醒
别忘了实现赋值运算符重载(可以用拷贝交换 idiom),不然你的二叉树在赋值操作时会出现浅拷贝问题,同样可能导致内存泄漏或者段错误哦!
内容的提问来源于stack exchange,提问作者Pape Sow Traore
相关产品推荐
相关产品推荐

