Pointers - passing ptr to ptr or passing the ptr address

I am trying to remove the left child (10) of a binary search test tree using two methods:

  • Method1: by passing a pointer to a pointer to the current node.
  • Method2: Skip the address of the pointer to the current node. This does not remove the node, but the delete call distorts the location of the pointer, causing printing failure of the nodes.

The tree looks like this and I'm trying to remove 10 and replace it with 5

20 | 10--|---30 | 5---| 

I have some understanding of pointers. But nonetheless, I do not understand 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 about pointers. If you see two calls to removeLeft(nodePtr) and removeLeft(&node) in the main() function.

  • How are these two different?
  • Why can't the second method achieve the desired result?
+4
source share
3 answers

In the first case, you pass the address of the pointer that exists in the tree, so you directly modify the contents of the tree.

In the second case, you pass the address of a variable that is local to main (). The tree does not change, and deleting from the address is access to the memory stack, so it causes a failure

0
source

You think too much about it. All you need is the removeLeft(Node*) function, which detaches the left node and removes it, recursively:

 void removeLeft(Node * p) { removeBoth(p->leftChild); // recurse, OK if null delete p->leftChild; // OK if already null p->leftChild = 0; // necessary to make recursion terminate } void removeBoth(Node * p) { if (!p) return; removeLeft(p); removeRight(p); } 
0
source

If you're bad with pointers, consider using smart pointers.
When using smart pointers instead of new Node use shared_ptr<Node> instead of Node * and make_shared(new Node); and delete all deleted files. Now you can handle pointers without worrying about memory deletion or corruption.

0
source

All Articles