簡體   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