在 Rust 中,Weak<T> 如何知道内部值何时被删除?

问题描述 投票:0回答:1

std::rc::Weak<T>
有以下定义:

pub struct Weak<T: ?Sized> {
    ptr: NonNull<RcBox<T>>,
}

在我的理解中,当没有更多的

Rc<T>
剩余时,
RcBox<T>
将被释放并且
Weak<T>.ptr
现在指向一个可能包含任何东西的地方。那么当在
upgrade()
上调用
Weak<T>
时,它怎么知道指针现在无效了?

Weak<T>::upgrade
有以下实现:

    pub fn upgrade(&self) -> Option<Rc<T>> {
        let inner = self.inner()?;

        if inner.strong() == 0 {
            None
        } else {
            unsafe {
                inner.inc_strong();
                Some(Rc::from_inner(self.ptr))
            }
        }
    }

这是否意味着当没有

RcBox<T>
留在野外时
Rc<T>
并没有真正被释放?如果是这样,那不会泄漏内存吗?

rust memory-management smart-pointers weak-references reference-counting
1个回答
2
投票

RcBox
不会被销毁,直到没有强指针弱指针剩余。

但是,当强计数达到零时,所包含的

T
掉落到位。这有效地破坏了包含的
T
,但不会释放
T
本身的记忆。

一旦弱计数也达到零,

RcBox
本身就会被释放。所以不,没有内存泄漏。

请注意,许多类型(例如

String
Vec
)管理单独的堆分配。如果你有一个
Rc<Vec<_>>
,例如,当强计数达到零但弱计数没有时,内部
Vec
的删除代码运行并删除它拥有的所有元素,并释放用于堆分配的堆分配存储它们。
Vec
本身用于保存堆指针、长度和容量的内存是 not 释放的,因为它由
RcBox
拥有。只有当强计数和弱计数都为零时,才会释放该分配。

© www.soinside.com 2019 - 2024. All rights reserved.