【发布时间】:2021-04-17 00:42:12
【问题描述】:
我正在调试我为二叉搜索树创建的复制构造函数,我通过监视原始树中节点的内存地址以及新创建的副本中的内存地址来做到这一点。节点由指向 Comparable 项(仅包含一个字符)的指针、该字符的出现次数以及指向其子节点(或 nullptr)的指针组成。
struct Node {
int count; // the number of occurences of the Comparable item (a char in this case)
Comparable* item; // the Comparable item being tracked
Node* leftChild;
Node* rightChild;
};
这是我的复制构造函数和助手:
BST::BST(const BST& tree)
{
rootPtr = copy(tree.rootPtr);
}
BST::Node* BST::copy(Node* root)
{
if (root == nullptr) {
return nullptr;
}
Node* temp = new Node;
Comparable* ptr = new Comparable;
*ptr = *root->item;
temp->item = ptr;
temp->count = root->count;
temp->rightChild = copy(root->rightChild);
temp->leftChild = copy(root->leftChild);
return temp;
}
我正在使用此函数将两棵树的数据以及它们在内存中的地址输出到控制台:
void BST::printInOrder(Node* root) const
{
if (root->leftChild != nullptr) {
printInOrder(root->leftChild);
}
cout << "&root: " << &root << " root: " << root << " :: " << *root->item << " " << root->count << endl;
// example output: &root: 00EFF388 root: 0113E858 :: W 1
if (root->rightChild != nullptr) {
printInOrder(root->rightChild);
}
}
这是原始树(顶部)和复制构造函数构造的树(底部)的控制台输出:
// original tree
&root: 00EFF470 root: 01140760 :: ! 1
&root: 00EFF558 root: 0113A018 :: H 1
&root: 00EFF388 root: 0113E858 :: W 1
&root: 00EFF2A0 root: 011406F0 :: d 1
&root: 00EFF470 root: 01134940 :: e 1
&root: 00EFF388 root: 01134A80 :: l 3
&root: 00EFF2A0 root: 0113E7E8 :: o 2
&root: 00EFF1B8 root: 01140680 :: r 1
// copy of original tree
&root: 00EFF470 root: 01140F90 :: ! 1
&root: 00EFF558 root: 011407A0 :: H 1
&root: 00EFF388 root: 01141390 :: W 1
&root: 00EFF2A0 root: 01140C90 :: d 1
&root: 00EFF470 root: 01140BE8 :: e 1
&root: 00EFF388 root: 011410D0 :: l 3
&root: 00EFF2A0 root: 01140E10 :: o 2
&root: 00EFF1B8 root: 01140DD0 :: r 1
您会注意到,对于两棵树,第二列 (root:) 包含从第一棵树到第二棵树的一组完全不同的内存地址,这是有道理的,并且让我相信我的复制构造函数作为Node* 指针指向内存中的不同地址(而这些地址包含相同的值)。
第一列 (&root:) 是我的困惑所在。我不明白为什么两棵树中的节点会用同一个指针指向它们的指针(这更适合图表)。
//column 1: //column 2:
//identical addresses //different addresses
&root: 00EFF470 root: 01140760 :: ! 1
&root: 00EFF470 root: 01140F90 :: ! 1
任何有关在何处进一步研究的见解或方向都会有所帮助,我当然是 C++ 新手,哦,如果这对此有所不同,我正在使用 Visual Studio 2019。
【问题讨论】:
-
显示创建/复制/打印树的代码。仅仅功能还不够运行程序。
-
如果将
void BST::printInOrder(Node* root) const更改为void BST::printInOrder(Node*& root) const会发生什么? (我无法测试它,因为您的代码不是minimal reproducible example。) -
当您打印
&root时,您会打印局部变量root的位置,它与树或其中的节点完全分开。
标签: c++ pointers memory-management copy-constructor