指针 - 将 ptr 传递给 ptr 或传递 ptr 的地址
我正在尝试使用两种方法删除示例二叉搜索树的左子节点 (10):
- 方法 1:通过将指针传递给当前节点的指针。
- 方法2:通过将指针的地址传递给当前节点。这不会删除节点,但调用删除会破坏指针排列,导致打印节点时崩溃。
树看起来像这样,我正在尝试删除 10 并将其替换为 5
<前><代码> 20 | 10--|---30 | 5---|
我对指针有一些了解。但是,我仍然不清楚指针的这种行为。
#include <iostream>
class Node
{
public:
Node(int key) : leftChild(0), rightChild(0), m_key (key){}
~Node(){}
Node *leftChild;
Node *rightChild;
int m_key;
};
Node* build1234(int, int, int, int);
void print(Node *);
void print1234(Node *);
void removeLeft(Node **nodePtr)
{
Node *oldPtr = *nodePtr;
if(*nodePtr)
{
*nodePtr = (*nodePtr)->leftChild;
delete oldPtr;
}
}
int main()
{
Node *demo1 = build1234(10, 20, 30, 5);
Node *demo2 = build1234(10, 20, 30, 5);
print1234(demo1);
print1234(demo2);
//Method1 - 10 is correctly removed with 5
Node **nodePtr = &demo1;
nodePtr = &(*nodePtr)->leftChild;
removeLeft(nodePtr);
print1234(demo1);
//Method2 - 10 is not removed
Node *node = demo2;
node = node->leftChild;
removeLeft(&node);
print1234(demo2);
return 0;
}
Node* build1234(int B, int A, int C, int D)
{
Node *root = new Node(A);
root->leftChild = new Node(B);
root->rightChild = new Node(C);
root->leftChild->leftChild = new Node(D);
return root;
}
void print(Node *node)
{
if(node)
{
print(node->leftChild);
std::cout << "[" << node->m_key << "]";
print(node->rightChild);
}
}
void print1234(Node *node)
{
std::cout << std::endl;
print(node);
}
注意:这个问题不是关于 BST 的,而是关于指针的。如果您在 main()
函数中看到对 removeLeft(nodePtr)
和 removeLeft(&node)
的两次调用。
- 这两者有何不同?
- 为什么第二种方法达不到预期的效果呢?
I am trying to remove the left child (10) of a sample binary search tree using two methods:
- Method1: By passing pointer to a pointer to the current node.
- Method2: By passing address of the pointer to the current node. This does not removes the node, but calling delete corrupts the pointer arrangement, causing a crash while printing the nodes.
The tree looks like this and I am trying to delete 10 and replace it with 5
20 | 10--|---30 | 5---|
I have some understanding of pointers. But still, I am not clear with this behavior of pointers.
#include <iostream>
class Node
{
public:
Node(int key) : leftChild(0), rightChild(0), m_key (key){}
~Node(){}
Node *leftChild;
Node *rightChild;
int m_key;
};
Node* build1234(int, int, int, int);
void print(Node *);
void print1234(Node *);
void removeLeft(Node **nodePtr)
{
Node *oldPtr = *nodePtr;
if(*nodePtr)
{
*nodePtr = (*nodePtr)->leftChild;
delete oldPtr;
}
}
int main()
{
Node *demo1 = build1234(10, 20, 30, 5);
Node *demo2 = build1234(10, 20, 30, 5);
print1234(demo1);
print1234(demo2);
//Method1 - 10 is correctly removed with 5
Node **nodePtr = &demo1;
nodePtr = &(*nodePtr)->leftChild;
removeLeft(nodePtr);
print1234(demo1);
//Method2 - 10 is not removed
Node *node = demo2;
node = node->leftChild;
removeLeft(&node);
print1234(demo2);
return 0;
}
Node* build1234(int B, int A, int C, int D)
{
Node *root = new Node(A);
root->leftChild = new Node(B);
root->rightChild = new Node(C);
root->leftChild->leftChild = new Node(D);
return root;
}
void print(Node *node)
{
if(node)
{
print(node->leftChild);
std::cout << "[" << node->m_key << "]";
print(node->rightChild);
}
}
void print1234(Node *node)
{
std::cout << std::endl;
print(node);
}
Note: This question is not about BST, but pointers. If you see the two calls to removeLeft(nodePtr)
and the removeLeft(&node)
in the main()
function.
- How are these two different?
- Why the second method fails to achieve the desired result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在第一种情况下,您传递的是树中存在的指针的地址,因此您直接修改树的内容。
在第二种情况下,您传递的是 main() 本地变量的地址。树没有被修改,从地址删除是访问栈内存,这就是崩溃的原因
In the first case, you are passing an address of a pointer that exists in the tree, so you are modifying the contents of the tree directly.
In the second case, you are passing an address of a variable that is local to main() instead. The tree is not modified, and deleting from the address is accessing stack memory, which is why it crashes
你想太多了。您所需要的只是一个函数
removeLeft(Node*)
,它可以递归地解开左侧节点并删除它:You're overthinking it. All you need is a function
removeLeft(Node*)
that unhooks the left node and deletes it, recursively:如果您不擅长使用指针,请考虑使用智能指针。
使用智能指针时,使用
shared_ptr
代替Node *
并使用make_shared(new Node);
代替new Node
code> 并删除所有删除内容。现在您可以处理指针而无需关心删除和内存损坏。If you are bad with pointers consider using smart pointers.
When using smart pointers use
shared_ptr<Node>
instead ofNode *
andmake_shared(new Node);
instead ofnew Node
and remove all deletes. now you can handle pointers without caring for deletes and memory corruption.