【问题标题】:delete right child makes parent left pointer point to nullptr删除右孩子使父左指针指向nullptr
【发布时间】:2016-06-02 03:15:51
【问题描述】:

感谢您检查我的问题,我目前有一个关于运算符“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;

            }
        }
    }

上面的代码是一个经典的搜索树移除算法。如果当前树只有两​​个节点,即根节点(例如 key 等于 3)和右子节点(例如 key 等于 4),那么当我删除节点 4 时,它会调用 remove 两次并转到这一行:

    delete oldNode;

这一行将删除“oldNode”,现在应该是 4。据我所知,删除操作符只会释放内存地址(地址与 oldNode 的值相同),这意味着它告诉操作系统该地址再次可用。所以我想当我打印出root的右指针(root->right)的值时,我应该得到一个地址。实际上,当我打印出来时,我得到了 0。所以当 root->right 改变时我的问题是什么?

希望我能清楚地解释我的问题。这可能是一个愚蠢的问题,如果我有任何混淆,请告诉我。

【问题讨论】:

    标签: c++ data-structures


    【解决方案1】:

    我认为您所看到的是在删除后使用指针是未定义的行为(直到 c++14)。

    对于 c++14:通过以这种方式变为无效的指针进行间接并将其传递给释放函数(双重删除)是未定义的行为。任何其他用途都是实现定义的。

    未定义的行为基本上允许实现在删除后对指针执行任何操作(甚至更改其值)。

    看起来您的实现在 delete 中设置了指向 nullptr 的指针的值。

    【讨论】:

    • 嗨,谢谢你的检查。实际上我记下了“oldNode = nullptr”。很抱歉造成混淆,我的问题可以理解为“在这个实现中,如果一个子节点被删除,何时以及谁将父节点的右指针设置为nullptr”
    【解决方案2】:

    我找到了答案,但在回答之前,让我先澄清一下我的问题。问题是询问何时删除子级,何时以及谁将其父级右指针设置为 nullptr。答案是这个函数有指针引用作为参数,当调用这个函数时,传递的参数本身会被设置为nullptr。例如传入root->right时,可以直接设置root->right为nullptr。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 2015-08-09
      • 1970-01-01
      • 1970-01-01
      • 2013-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多