I created a tree data structure class that allocates memory for a node implementation. The remove function is successful in finding and deleting the allocated memory for the tree node, but I have trouble setting the actual node to nullptr. My remove function creates a tree node pointer and sets it to the address of the node to be deleted. I delete that pointer and set it to nullptr, but the tree node is only affected by delete and is not set to nullptr. Therefore, it becomes junk and messes up my program.
The problem starts at case 2 where my remove function checks if the node is a leaf.
template <class DType>
bool Tree<DType>::remove(DType toDelete)
{
if (head == nullptr) {
return false;
}
if (!check_existence(toDelete)) // CASE 1: Node does not exist.
{
std::cout << "Remove Error: " << toDelete << " does not exist." << std::endl;
return false;
}
TreeNode<DType>* nodeToDelete = find(toDelete); // Address of node to be deleted.
TreeNode<DType>* nodeToDelete_left = nodeToDelete->get_left();
TreeNode<DType>* nodeToDelete_right = nodeToDelete->get_right();
if (!(nodeToDelete_left) && !(nodeToDelete_right)) // CASE 2: Node is a leaf.
{
nodeToDelete->delete_nodes(nodeToDelete);
nodeToDelete = nullptr;
nodeCount--;
return true;
}
TreeNode<DType>* temp = nullptr;
if ((nodeToDelete_left != nullptr) ^ (nodeToDelete_right != nullptr)) // CASE 3: Node has one child.
{
temp = nodeToDelete;
if (nodeToDelete_left) // 3A: Left child exists
{
nodeToDelete = nodeToDelete_left;
}
if (nodeToDelete_right) // 3B: Right child exists.
{
nodeToDelete = nodeToDelete_right;
}
delete temp;
temp = nullptr;
nodeCount--;
return true;
}
// CASE 4: Node has two children
temp = find_min(nodeToDelete_right);
nodeToDelete->set_data(temp->get_data());
delete temp;
temp = nullptr;
nodeCount--;
return true;
}
-
You would need to find pointer to the pointer. Otherwise you just pass the copy of the pointer. Having copy of the pointer you are still able ro delete object that it is pointing to, but you can't change it's value. Consider using shared_ptr - then you can just pass its copy and use reset() method to delete underlying object and automatically set its pointer to nullptr.mlc– mlc2020年04月21日 20:58:59 +00:00Commented Apr 21, 2020 at 20:58
2 Answers 2
DType x;
DType* ptr = &x;
DType** ptrptr = &ptr;
std::cout << ptr << '\n'; // some address will be printed
// setting a pointer a pointer is pointing to, to nullptr by dereferencing the
// pointer-pointer
*ptrptr = nullptr;
std::cout << ptr << '\n'; // nullptr representation (0) printed
Comments
You're taking a copy of the pointer returned by find. Setting it to nullptr won't change the value of the original (you can, however, delete the object pointed to by the original).
Make sure find returns a reference to pointer (e.g. TreeNode<DType>*&), and that your variables are declared accordingly (e.g. TreeNode<DType>*& nodeToDelete).