std::rc::Weak<T>的定义如下:

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

在我的理解中,当没有更多的Rc<T>个时,RcBox<T>个将被释放,Weak<T>.ptr个现在指向一个可能包含任何东西的地方.那么,当在Weak<T>上调用upgrade()时,它如何知道指针现在是无效的?

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))
            }
        }
    }

这是否意味着,当野生动物中没有Rc<T>只时,RcBox<T>只就不是真正的自由了?如果是这样的话,这不会泄露内存吗?

推荐答案

在没有强大的or个弱指针之前,这RcBox个不会被摧毁.

然而,当强计数达到零时,所包含的Tdropped in place.这将有效地销毁所包含的T,但不会释放T本身的内存.这就是Weak知道内部值是否被删除的方式--如果在强计数为零时try 将Weak升级到Rc,操作将失败并返回None.

一旦弱计数也达到零,RcBox本身就被释放了.所以没有,没有内存泄漏.

请注意,许多类型(如StringVec)管理单独的堆分配.例如,如果您有一个Rc<Vec<_>>,当强计数达到零而弱计数没有达到零时,内部Vec的删除代码将运行并删除其拥有的所有元素,并释放用于存储这些元素的堆分配.Vec本身用来保存堆指针、长度和容量的内存被释放not,因为它由RcBox拥有.只有当强计数和弱计数都达到零时,这种配置才会释放.

Rust相关问答推荐

当两者都有效时,为什么Rust编译器建议添加';&;而不是';*';?

修改切片/引用数组

如何实现泛型枚举的`Serde::Desialize`特性

通过不同的字段进行散列和排序的 struct (需要不同的EQ实现)

有没有办法指定只在Rust的测试中有效的断言?

写入引用会更新基础值,但引用会打印意外的值

如何迭代属性以判断相等性?

为什么实现特征的对象期望比具体对象有更长的生命周期?

带引脚和不带引脚的比较功能

go 重并堆积MPSC通道消息

为什么Rust中无法推断生命周期?

当在lambda中通过引用传递时,为什么会出现终身/类型不匹配错误?

全面的 Rust Ch.16.2 - 使用捕获和 const 表达式的 struct 模式匹配

如何从 rust 中的同一父目录导入文件

std::vector::shrink_to_fit 如何在 Rust 中工作?

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

打印 `format_args!` 时borrow 时临时值丢失

为什么我可以同时传递可变和不可变引用?

用逗号分隔字符串,但在标记中使用逗号

有没有办法隐藏类型定义?