感谢您检查我的问题,我目前有一个关于运算符“delete”的非常基本的问题,它似乎可以自动将指针值更改为 nullptr。让我举个例子:
template <typename T>
void Tree<T>::remove(const unsigned& index, TreeNode<T>*& tree)
{
if(tree == nullptr)
{
std::cerr << "remove: can't find target" << std::endl;
}
else if(index < tree->index)
{
remove(index, tree->left);
}
else if(index > tree->index)
{
remove(index, tree->right);
}
else if(index == tree->index)
{
if(tree->degree() == 2)
{
tree->index = findMin(tree->right)->index;
tree->value = findMin(tree->right)->value;
remove(tree->index, tree->right);
}
else
{
auto oldNode = tree;
tree = (tree->left != nullptr) ? tree->left: tree->right;
delete oldNode;
// oldNode = nullptr;
}
}
}
上面的代码是一个经典的搜索树删除算法。如果当前树只有两个节点,即根节点(例如键等于 3)和右子节点(例如键等于 4),那么当我删除节点 4 时,它将调用两次删除并转到这一行:
delete oldNode;
这行将删除“oldNode”,它现在应该是 4。据我所知,删除运算符只会释放内存地址(该地址与 oldNode 的值相同),这意味着它告诉操作系统该地址再次可用。所以我想当我打印出 root 的右指针 (root->right) 的值时,我应该得到一个地址。实际上,当我打印出来时,我得到 0。所以我的问题是 root->right 改变了吗?
希望我能清楚地解释我的问题。这可能是一个愚蠢的问题,如果我有任何混淆,请告诉我。
最佳答案
我认为您看到的是在删除之后使用指针是未定义的行为(直到 c++14)。
对于 c++14:通过以这种方式变得无效的指针进行间接寻址并将其传递给释放函数(双删除)是未定义的行为。任何其他用途都是实现定义的。
未定义的行为基本上允许实现在删除后对指针做任何它想做的事情(甚至改变它的值)。
看起来您的实现将指针的值设置为 delete 中的 nullptr。
关于c++ - 删除右 child 使父左指针指向 nullptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37582027/