[英]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
類型。
在pTreeNode
( std::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 =
正是為了避免這些問題。
- 我在做什么不安全?
不,我能看到它是安全的。 left
或right
節點實例將保持活動狀態,直到它們的引用計數降至零。
- 如果它不安全,我該怎么做才能解決這個問題?
您應該注意的唯一相關事項是不要將任何節點shared_ptr
為shared_ptr
在樹實現之外。 這些應該是std::weak_ptr
或原始指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.