感谢您检查我的问题,我目前对运算符“删除”有一个非常基本的问题,它似乎可以自动将指针值更改为nullptr。让我举个例子:
def update_my_model_status(model,id,field, value)
@model = model.find(id)
@model.update(field: value)
end
上面的代码是一个经典的搜索树删除算法。如果当前树只有两个节点是root(例如,键等于3)和右子节点(例如,键等于4),那么当我删除节点4时,它将调用remove两次并转到此行:
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;
}
}
}
此行将删除“oldNode”,现在应为4。据我所知,删除操作符将释放内存地址(该地址与oldNode的值相同),这意味着它告诉操作系统该地址再次可用。所以我想当我打印出root的右指针(root-&gt; right)的值时,我应该得到一个地址。实际上,当我打印出来时,我得到0.所以当root-&gt;右边改变了我的问题?
希望我能清楚地解释我的问题。这可能是一个愚蠢的问题,让我知道如果我有任何困惑。
答案 0 :(得分:1)
我认为你所看到的是删除后使用指针是未定义的行为(直到c ++ 14)。
对于c ++ 14:通过以这种方式变为无效的指针并将其传递给释放函数(双删除)的间接是未定义的行为。任何其他用途都是实现定义的。
未定义的行为基本上允许实现在删除后使用指针执行任何操作(甚至更改其值)。
看起来你的实现在delete中设置了指向nullptr的指针的值。
答案 1 :(得分:0)
我找到了答案,但在回答之前,让我澄清一下我的问题。问题是询问何时删除子项,何时以及谁将其父权限指针设置为nullptr。答案是这个函数有指针引用作为参数,当调用这个函数时,传递的参数本身将被设置为nullptr。例如,当传入root-&gt; right时,root-&gt; right可以直接设置为nullptr。