Rc与Box区别

Rust Rc(引用计数)方法详解 总结一下,Rust中的Rc提供了一种方便的共享所有权的机制,通过引用计数来跟踪值的使用情况。使用Rc时,需要注意循环引用的问题,因为Rc无法处理循环引用的情况,可能导致内存泄漏。它允许多个引用同时指向同一个值,通过计数器来跟踪当前有多少个引用指向该值,从而在引用计数为零时自动释放该值。除了上述方法之外,Rc还实现了Deref和Drop trait,使得可以像操作普通引用一样操作Rc指针。方法,通过Deref trait,我们可以直接在Rc指针上调用这个方法。方法获取当前引用计数,并打印输出。 阅读详情

咋一看觉得这两个概念差的很远,其实他们之间还是有联系的:

  • 相同点:
    他们都是在堆上分配资源,都只是保存了一个指向堆上的指针
  • 区别:
    • Box就是一个简单的指向堆的指针,并且指向堆的这个区域的指针只能有一个,owner lifetime结束就会释放堆上的资源
    • Rc增加了一个计数(准确来说是两个指针),可以多个指针指向堆的这个区域,等所有的引用者lifetime结束了才释放堆上的资源

下面的代码为了看起来清爽点删除了注释

1 这个是Rc的定义

struct RcBox<T: ?Sized> {
    strong: Cell<usize>,
    weak: Cell<usize>,
    value: T,
}

pub struct Rc<T: ?Sized> {
    _ptr: NonZero<*mut RcBox<T>>,
}

其中NonZero很简单,就是简单的包装了下T

pub struct NonZero<T: Zeroable>(T);

具体可以看:
http://doc.rust-lang.org/stable/src/alloc/rc.rs.html#172

2 Box定义如下:

pub struct Box<T>(Unique<T>);

http://doc.rust-lang.org/stable/src/alloc/boxed.rs.html#94

其中Unique定义如下:

pub struct Unique<T: ?Sized> {
    pointer: NonZero<*const T>,
    _marker: PhantomData<T>,
}

http://doc.rust-lang.org/stable/src/core/ptr.rs.html#513-521
Unique里的marker是不占用存储空间的,可以暂时忽略掉

3 具体的例子:

use std::rc::Rc;

#[derive(Debug)]
struct Foo(i32);


fn main(){
    let r:Rc<Foo>;
    let b:Box<Foo>;
    {
        let r1 = Rc::new(Foo(100));
        println!("r1:{:p}",&*r1);
        //clone计数
        r = r1.clone();
        //多处引用,都可以分别访问
        println!("r1:{:?}",r1);

        let b1 = Box::new(Foo(200));
        println!("b1:{:p},data:{}",&*b1,(*b1).0);
        //owner ship 转移了
        b = b1;
        //b1不能再访问
        //println!("{:?}",b1);
    }
    println!("{:?}",r);
    println!("r:{:p}",&*r);

    println!("{:?}",b);
    println!("b:{:p}",&*b);
}

Play地址:http://is.gd/rGBLaW
输出结果:

r1:0x7f621582d010
r1:Foo(100)
b1:0x7f6215823020,data:200
Foo(100)
r:0x7f621582d010
Foo(200)
b:0x7f6215823020

Box,Rc 都是在堆上分配的,那么都可以存在于定义它的范围之外。

  • Rc是通过引用计数的方式获得更长的lifetime,这儿r=r1.clone()就把堆上的对象的lifetime增加到了外层block对应的lifetime
  • Box通过转移owner ship的方式把b1传递给了b从而让Box指向的堆上的资源没有被释放。

在这种情况下都可以通过不同的方式实现lifetime的扩张,但还是有区别的:

  • Box方式转移了owner ship之后就不能再访问原来的b1了,也就是只能一个指针指向Box在堆上分配的资源
  • Rc通过增加引用计数的方式实现了lifetime的扩张,并且r1还是继续使用的
恋爱脑学Rust之Box与RC的对比 Rc的共享之爱Rc像阿丽的共享理念,多人共享访问,所有人都可以共同拥有心之花,并增加引用计数来管理。Box的唯一之爱Box像小明的独占信念,所有权单一,只能有一个唯一的持有者,不允许随意转让。这两种智能指针在 Rust 中适合不同的场景:当需要共享所有权时,Rc是理想选择,而当独占所有权是必要时,Box是最佳选择。Rust 的智能指针机制帮助阿丽和小明在自己的爱情中找到了平衡,使得心之花在不同场景中都绽放得美丽而安全。 阅读详情

相关推荐

[重学Rust]之智能指针

【Rust智能指针全解析】本文系统梳理Rust五大智能指针:Box(堆内存分配)、RefCell(运行时借用检查)、Rc/Arc(单/多线程引用计数)、Mutex(互斥锁)和RwLock(读写锁)。通过代码示例详解各自特性:Box实现堆栈分离;RefCell实现编译期不可变值的运行时可变借用;Rc/Arc管理共享所有权;Mutex保障线程独占访问;RwLock优化读多写少场景。特别对比Mutex与RwLock的适用场景,帮助开发者根据线程安全需求灵活选择。文章附带完整示例代码,适合Rust开发者深入理解所有

盹猫的博客 1521

Rust: Box 智能指针进阶 - Rc、RefCell、Weak

Rust: Box 智能指针进阶 - Rc、RefCell、Weak 文章目录Rust: Box 智能指针进阶 - Rc、RefCell、Weak正文1. Box 类型复习2. 自定义模拟 Box 类型3. 递归类型定义4. Box 进阶:Rc5. Box 进阶:RefCell6. 循环依赖 & Weak7. 结论其他资源参考连接完整代码示例 正文 1. Box 类型复习 Rust 内置类型: Box、Option、Result Box 为一种特别的引用类型,实际数据存储在堆上 Box 作为引用类

超悠閒的博客 2653

致远OA公文管理模块相关操作

致远oa协同办公系统 公文管理模板 相关操作

weixin_59666050的博客 4271

rust学习——智能指针Rc

Rc/Arc是不可变引用,你无法修改它指向的值,只能进行读取,如果要修改,需要配合后面章节的内部可变性RefCell或互斥锁Mutex一旦最后一个拥有者消失,则资源会自动被回收,这个生命周期是在编译期就确定下来的Rc只能用于同一线程内部,想要用于线程之间的对象共享,你需要使用ArcRc是一个智能指针,实现了Deref特征,因此你无需先解开Rc指针,再使用里面的T,而是可以直接使用T,例如上例中的。

mirana的专栏 1380

AlphaFold3实战:用它预测抗体结构,我的CDR H3环RMSD降到了2Å以内

本文详细介绍了如何利用AlphaFold3(AF3)高精度预测抗体结构,特别是CDR H3环的建模,其RMSD可降至2Å以内。通过实战演示从序列输入到结构优化的全流程,包括参数配置、置信度指标解读及结果分析,帮助研究人员快速掌握AF3在抗体药物研发中的应用。

weixin_29224529的博客 187

SPSS_Process—简单&平行&链式中介模型

本篇文章介绍采用SPSS的插件Process对简单中介、链式中介、平行中介模型进行检验的操作方法及结果解读。

m0_54401011的博客 4万+

彻底搞懂Rust智能指针:Box/Rc/Arc/RefCell应用场景全解析

你还在为Rust的内存管理头疼吗?面对Box、Rc、Arc和RefCell这些智能指针,是不是不知道该在什么时候用哪个?本文将通过实际场景和代码示例,帮你彻底搞懂这四种智能指针的核心用法,解决90%的ownership问题。读完本文你将能够:掌握每种智能指针的适用场景、避免常见的内存安全错误、写出更优雅的Rust代码。 ## 什么是智能指针 智能指针(Smart Pointer)是Rust中一...

gitblog_00278的博客 464

基于大疆TSDK与Pix4D的热红外数据工程化处理:从RJPG到温度正射影像的完整工作流

本文详细介绍了基于大疆TSDK与Pix4D的热红外数据工程化处理完整工作流。通过Python脚本自动化解析RJPG格式的热红外图像,提取并转换其中的原始辐射数据为包含真实温度信息的TIFF文件,再结合Pix4Dmapper进行批量拼接,最终生成可直接用于GIS分析的温度正射影像图。该流程解决了手动处理效率低下、参数校准复杂等难题,实现了从原始数据到定量分析成果的高效、准确、可重复生产。

weixin_29161785的博客 375

Rust 中的 Rc智能指针

Rust 中的 Rc智能指针 1 初识 Rc 先看个简单例子: use std::rc::Rc; fn main() { let x = Rc::new(123); println!("{:?}", x); } --------------------------------------------------- cargo run 123 这个与 Box 指针几乎一样,二者区别在于 clone() 的具体执行过程。 2 clone() 方法 看下面的例子: use std::rc::Rc

程序猿视角 1260

Windows 下 Codex MCP 服务配置全攻略:从环境搭建到实战避坑

本文详细介绍了在Windows系统下配置Codex MCP服务的完整流程与实战避坑指南。内容涵盖从Node.js环境搭建、Codex CLI安装,到核心配置文件config.toml的编写与解析,并重点解决了Windows平台特有的环境变量设置、MCP服务启动命令适配等关键难点,帮助开发者顺利完成从环境准备到编辑器插件连接的整个配置过程。

weixin_28826545的博客 2067

从底层结构开始学习FPGA(7)----进位链CARRY4

进位链CARRY4在FPGA实现加减法运算时扮演了什么角色?

孤独的单刀 1万+

Rust 中的智能指针机制:Box、Rc、Arc 的选择艺术

Rust 的智能指针系统是其所有权模型的自然延伸,但也是最容易被误解的部分。Box<T>、Rc<T> 和 Arc<T> 三种智能指针虽然看似简单,但它们各自解决了不同的所有权问题,对应着不同的执行模型。掌握何时、为什么以及如何使用每一种指针,是从 Rust 初学者进阶到系统工程师的关键门槛。

2301_81152266的博客 1081

【100%通过率】华为OD机试真题2026双机位C卷 C语言 实现【加密算法】

【100%通过率】华为OD机试真题2026双机位C卷 Python&JS 实现【加密算法】有一种特殊的加密算法,明文为一段数字串,经过密码本查找转换,生成另一段密文数字串。规则如下

MISAYAONE的博客 646

rust智能指针

Deref隐式转换将实现了Deref的类型的引用转换为另一种类型的引用。一种无法在编译时知道大小的类型是递归类型,其值的一部分可以是自身类型的另一个值。Deref trait使智能指针表现的像引用一样,这样就可以编写既用于引用、又用于智能指针的代码。每次使用 * 时, * 运算符都被替换成先调用deref方法再使用 * 解引用的操作,且只会发生一次,不会无限递归替换 * 操作符,解引用出i32类型的值就停止了。是一个指针,它的大小是确定的,所以将Box作为Cons的成员,这样List的大小就确定了。

void的博客 875

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

RUST笔记:初识RefCell

初识RefCell

m0_54948954的博客 713

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

【Rust中的智能指针】

传统的指针,如C++中的裸指针,需要开发者自己申请和释放,如果开发者在使用过程中疏漏了回收,将会造成内存泄漏,在部署实施时也会有oom的风险,智能指针即是为了解决这类问题而出现的,老生常谈的shared_ptr,unique_ptr,weak_ptr等,都是通过设计使得代码自动管理回收堆上的内存,提高代码的健壮性和方便性。Rust由于其严格的安全性和所有权机制,除unsafe写法外,所有的堆内存都是通过语言特性管理的。

m0_37719524的博客 1233

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Rust语言教程(8) - 所有权

Rust语言教程(8) - 所有权 我们从第2讲到第7讲这6讲,在堆上分配了不少对象,但是类似于C++的delete运算符仍然没有出场过。因为Rust有作用域规则,在超出作用域之后会自动释放掉。 移动语义和复制语义 我们来复习下移动语义。 先看一段代码: let mut c_0 = Complex{real:0, imagine:0}; println!("{}",c_0); println!("{}",c_0.imagine); println!("{:?}",c_0);

lusing的专栏 400

rust学习——智能指针

Rust 标准库中定义的那些智能指针,虽重但强,可以提供比引用更多的功能特性,例如本章将讨论的引用计数智能指针。该智能指针允许你同时拥有同一个数据的多个所有权,它会跟踪每一个所有者并进行计数,当所有的所有者都归还后,该智能指针及指向的数据将自动被清理释放。而智能指针则不然,它虽然也号称指针,但是它是一个复杂的家伙:通过比引用更复杂的数据结构,包含比引用更多的信息,例如元数据,当前长度,最大可用长度等。,它们的数据结构中不仅仅包含了指向底层数据的指针,还包含了当前长度、最大长度等信息,其中。

mirana的专栏 938

rust复习笔记5

构建命令行程序 获取命令行参数的值,我们需要一个 Rust 标准库提供的函数,也就是std::env::args。 当所需函数嵌套了多于一层模块时,通常将父模块引入作用域,而不是其自身。 std::fs来处理文件 获取环境变量的方法,env::var(环境变量名) 标准库提供了eprintln!宏来打印到标准错误流 闭包 闭包的定义以一对竖线(|)开始,在竖线中指定闭包的参数...

luo222的专栏 323

rust实战系列三十:静态方法

Box的一系列方法Box::into_raw(b: Self)Box::leak(b:Self),以及Rc的一系列方法Rc::try_unwrap(this: Self)Rc::downgrade(this:&Self),都是这种情况。它们的receiver不是self关 键字,这样设计的目的是强制用户用Rc::downgrade(&obj)的形式调用,而禁 止obj.downgrade()形式的调用。没有receiver参数的方法(第一个参数不是self参数的方法)称作“静态方法”。

Mr_Roki的博客 517

Rust 的智能指针

Rust 的智能指针

一起coding,一起嗨。 604

指针的三种面孔:深度拆解 Rust 中的 Box、Rc 与 Arc

的差异与内部机制,我们能在 Rust 项目中更加自信地管理内存与所有权:既保持安全,也守住性能边界。由于 Arc 只保证引用计数安全,内部数据仍需同步原语保护。应按并发需求选择,并在热路径减少克隆次数。提供独占所有权:内部仅包含一个指向被管理对象的裸指针,结合实现运行时可变性,但要防范循环引用导致的内存泄漏。允许与 C 交互,但需确保只调用一次还原。支持写时复制,独占时可直接修改底层数据。通过两粒引用计数跟踪共享状态:强引用。:多线程安全的原子引用计数结构,通过。实现锁自由的计数更新。

TD0011的博客 344

Rust开发入门之Rust 智能指针详解

Rust 智能指针是其内存安全机制的重要组成部分,通过所有权系统实现高效安全的内存管理。标准库提供了多种智能指针:Box<T>用于堆分配和递归类型;Rc<T>实现单线程的多所有权共享;Arc<T>是其线程安全版本;RefCell<T>提供内部可变性,将借用检查推迟到运行时。这些指针通过实现Deref和Drop特征,支持自动解引用和资源清理。合理组合使用这些指针(如Rc<RefCell<T>>)可以在遵循Rust安全规则的同时满足复杂场景

风中追风 994

Rust智能指针的奇妙之旅:从踩坑到顿悟

上个月我在写一个多线程文件处理工具时,程序莫名其妙地崩了。错误信息指向一个看似平常的变量传递,编译器冷冷地告诉我:“value moved here”。那一刻我才意识到,是时候认真搞懂Rust的智能指针了。Box、Rc、Arc,这三个家伙看起来都是在管理内存,但它们各自的脾气和适用场景完全不同。

L040821的博客 491
上一篇: 多个closure引用同一个变量,并且可能需要mut borrow
下一篇: 含有重复元素的二分查找算法
varding
博客等级 码龄17年 115粉丝 116原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值