繁体   English   中英

使用智能指针进行C ++二叉搜索树

[英]Using smart pointers for C++ binary search tree

我用c ++实现了二叉搜索树。 我没有使用裸指针指向节点子节点,而是使用了std::shared_ptr 树的节点如下实现

struct treeNode;
typedef std::shared_ptr<treeNode> pTreeNode;

struct treeNode {
    T key;
    pTreeNode left;
    pTreeNode right;
    treeNode(T key) : key(key), left(nullptr), right(nullptr) {}
};

从BST中删除节点时,其中一种情况是节点只有一个子节点。 该子节点简单地替换该节点,如下所示:

             |        remove node                  
            node      --------->     |
               \                    right 
              right                

在类似的Java实现中,这可以编码为:

node = node.getRight();

在我的C ++实现中,它是:

node = node->right;

其中node是pTreeNode类型。

pTreeNodestd::shared_ptr<TreeNode> )上调用=运算符时,将调用node的析构函数。 指向底层TreeNode的共享指针的数量为1,因此TreeNode被销毁以释放其内存。 当调用TreeNode (默认)析构函数时,会销毁其每个成员。 这肯定会导致pTreeNode right成员被破坏。 问题是node->right是分配给node 在测试我的BST时,它似乎工作正常,没有错误/内存泄漏。

  • 我在做什么不安全?
  • 如果它不安全,我该怎么做才能解决这个问题?

我认为可能有用的“黑客”是制作另一个指针以增加其引用计数。 这是一个适当的解决方案吗?

//increase reference to node->right by 1 so it doesn't get destroyed
pTreeNode temp(node->right);
node = node->right;

你显然是假设,在

node = right;

shared_ptr的赋值运算符可以在从right读取之前(或在增加right使用的引用计数之前)减少节点的计数。 但是,根据cppreference,使用

template<typename T>
template<typename U>
std::shared_ptr<T> &std::shared_ptr<T>::operator =(const std::shared_ptr<U> &);

node = right; // std::shared_ptr<treeNode>

相当于

std::shared_ptr<treeNode>(right).swap(node);

这是安全的,因为销毁旧的node之前复制了right 顺便说一句,我自己实现了一个共享指针,我看到它“清理”旧值是我在operator =做的最后一件事operator =正是为了避免这些问题。

  • 我在做什么不安全?

不,我能看到它是安全的。 leftright节点实例将保持活动状态,直到它们的引用计数降至零。

  • 如果它不安全,我该怎么做才能解决这个问题?

您应该注意的唯一相关事项是不要将任何节点shared_ptrshared_ptr在树实现之外。 这些应该是std::weak_ptr或原始指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM