Rust 学习笔记:关于智能指针的练习题

Rust 智能指针 在Rust中,智能指针是封装了原始指针(如*const T或*mut T)的封装类型,它们在运行时持有关联数据的生命周期。智能指针的主要作用是提供对内存的安全管理,同时避免了传统的指针操作中常见的错误,如悬垂指针、野指针和数据竞争等。Rust的智能指针为开发者提供了一种强大的工具,它们不仅简化了内存管理,还提高了代码的健壮性和可读性。通过合理使用智能指针,可以有效地利用Rust的所有权系统,避免内存泄漏和其他内存相关错误。 阅读详情

Rust 学习笔记:关于智能指针的练习题

参考视频:

  1. https://www.bilibili.com/video/BV1SJ9vYsEfR
  2. https://www.bilibili.com/video/BV1Q79vYdEGx
  3. https://www.bilibili.com/video/BV1Q79vYdEgo
  4. https://www.bilibili.com/video/BV1Rg9vYhExC
  5. https://www.bilibili.com/video/BV1dLRVYrEfQ
  6. https://www.bilibili.com/video/BV1RGRnYoEiJ

问题一

以下程序能否通过编译?若能,输出是?

fn main() {
    let mut n = 1;
    let b = Box::new(&mut n);
    **b += 1;
    
    println!("{}", n);
}

答:可以通过编译。输出为 2。

问题二

假设我们有一个程序,其中有一个变量:

let x = [Box<(usize, usize)>; 4] = /* ... */

对于一个 64 位架构的编译目标,x 在栈上所占用的最小内存大小是多少?

答:32 字节。

在 Rust 中,变量 x 的类型为 [Box<(usize, usize)>; 4],这是一个包含 4 个元素的数组,每个元素是一个 Box<(usize, usize)>。Box<T> 是一个智能指针,它在栈上仅存储一个指针,在 64 位架构上,指针的大小固定为 8 字节,故数组大小 = 4 * 8 = 32 字节。

问题三

以下程序能否通过编译?若能,输出是?

use std::ops::Deref;

#[derive(Copy, Clone)]
struct AccessLogger(i32);

impl Deref for AccessLogger {
    type Target = i32;
    fn deref(&self) -> &Self::Target {
        println!("deref");
        &self.0
    }
}

fn main() {
    let n = AccessLogger(-1);
    let x = *n + 1;
    let n2 = n;
    println!("{} {}", x, *n);
}

答:可以通过编译。输出为:

deref
deref
0 -1

问题四

以下程序能否通过编译?若能,输出是?

struct Example(i32);

impl Drop for Example {
    fn drop(&mut self) {
        self.0 += 1;
        println!("drop {}", self.0);
    }
}

fn main() {
    let e = Example(0);
    drop(e);
    drop(e);
}

答:不能通过编译。

问题五

在这里插入图片描述

答:{ s }、drop(s)、(|_|())(s)。

第一个利用了作用域,s 变量离开作用域时自动被清除。

第二个调用了 std::mem::drop 函数,显式销毁了 s 变量。

第三个是一个空闭包, 闭包获取了 s 的所有权,离开闭包时 s 被销毁。

第四个是不被允许的。

问题六

以下程序能否通过编译?若能,输出是?

use std::rc::Rc;

fn main() {
    let n = Rc::new(1);
    let mut n2 = Rc::clone(&n);
    *n2 += 1;
    println!("{}", n);
}

答:不能通过编译。

Rc::clone 是浅拷贝,并没有获取值的所有权。

问题七

以下程序能否通过编译?若能,输出是?

use std::rc::Rc;

struct Example;

impl Drop for Example {
    fn drop(&mut self) {
        println!("drop");
    }
}

fn main() {
    let x = Rc::new(Example);
    let y = Rc::clone(&x);
    println!("A");
    drop(x);
    println!("B");
    drop(y);
    println!("C");
}

答:可以通过编译。输出为:

A
B
drop
C

销毁 x 时,对 Example 的引用计数为 1。只有当 y 也被销毁时,引用计数才为 0,执行 drop 方法。

问题八

以下哪项最好地描述了 Rust 中内部可变性的概念?

A. 将 unsafe 代码包装在安全的 API 中
B. 允许借用检查器在运行时强制执行内存安全
C. 允许数据结构内部的数据被修改
D. 允许通过不可变引用修改数据

答:D。

问题九

在这里插入图片描述

答:RefCell<usize>。

问题十

考虑以下未检查内部值是否被借用的错误 RefCell 实现:

use std::cell::UnsafeCell;

struct BadRefCell<T>(UnsafeCell<T>);

impl<T> BadRefCell<T> {
    pub fn borrow_mut(&self) -> &mut T {
        unsafe { &mut *self.0.get() }
    }
}

假设我们有如下 BadRefCell:

    let v = BadRefCell(UnsafeCell::new(vec![1, 2, 3]));

以下哪个代码片段在使用此 API 时会违反内存安全?

A.

    drop(v.borrow_mut());
    drop(v.borrow_mut());

B.

    let v1 = v.borrow_mut();
    let v2 = v.borrow_mut();
    v1.push(4);
    v2.push(5);

C.

    let v1 = v.borrow_mut();
    let n = &v1[0];
    v.borrow_mut().push(0);
    println!("{}", n);

D.

    v.borrow_mut().push(0);
    let n = v.borrow_mut()[0];
    println!("{}", n);

答:C。

获取 v 的可变引用后,向其中插入数据,可能会变更值在堆上的位置。此时再访问 n,可能发生内存泄漏,使得 n 变成一个悬垂引用。

数组 [1, 2, 3] 太小了,插入 1 个元素不一定会导致位置变化。我们改用一个包含 100000 个元素的数组,完整代码如下:

use std::cell::UnsafeCell;

struct BadRefCell<T>(UnsafeCell<T>);

impl<T> BadRefCell<T> {
    pub fn borrow_mut(&self) -> &mut T {
        unsafe { &mut *self.0.get() }
    }
}

fn main() {
    let v = BadRefCell(UnsafeCell::new(vec![1; 10000]));
    
    let v1 = v.borrow_mut();
    let n = &v1[0];
    v.borrow_mut().push(0);
    println!("{}", n);
}

运行结果:

在这里插入图片描述

理论上应该打印 1。显然这段代码违反内存安全,但还是通过了 Rust 的编译和运行时检查。

问题十一

以下程序能否通过编译?若能,输出是?

use std::rc::Rc;

fn main() {
    let r1 = Rc::new(0);
    let r4 = {
        let r2 = Rc::clone(&r1);
        Rc::downgrade(&r2)
    };
    let r5 =  Rc::clone(&r1);
    let r6 = r4.upgrade();
    println!("{} {}", Rc::strong_count(&r1), Rc::weak_count(&r1));
}

答:可以通过编译。输出 3 1。

r1、r2、r5 对其 Rc<T> 存在强引用,r4 为弱引用。

【Rust智能指针】Rust智能指针原理剖析与应用指导 Rust语言以其内存安全和零成本抽象的特性而闻名,其中智能指针是实现这些特性的重要组成部分。 与C++中的智能指针类似,Rust的智能指针提供了比普通引用更丰富的功能,但在实现和使用上有着Rust特有的设计哲学。 智能指针是Rust中一种特殊的数据结构,它们不仅包含指针功能,还附加了额外的元数据和功能。Rust标准库提供了多种智能指针类型,每种都有其特定的用途。 阅读详情

相关推荐

SAP 银企直连实战:从零构建 DMEEX 格式树的配置与调试指南

本文详细介绍了SAP银企直连中DMEEX格式树的配置与调试方法,涵盖从基础认知到实战技巧的全流程。通过具体案例解析,帮助财务顾问快速掌握建设银行付款报文的格式树搭建、字段映射及调试优化,提升企业支付效率与准确性。

weixin_42526015的博客 566

rust智能指针

特性引用 (&T 和 &mut T)智能指针(如 Box、Rc)所有权引用没有所有权,只是借用数据智能指针拥有数据的所有权内存管理不负责内存管理负责内存管理,通常有自动销毁机制生命周期有明确的生命周期生命周期取决于智能指针本身数据存储位置引用通常指向栈或堆上的数据智能指针通常分配堆上的内存操作只提供对数据的访问提供更多的操作功能,如引用计数、自动清理等线程安全不保证线程安全一些智能指针(如 Arc)是线程安全的MyBox(x)

喜欢打篮球的普通人 1798

资产会计 Transaction Type 与业务交易的 Post to Affiliated Company 不一致导致的 AAPO176:成因剖析与修复指引

本文解析了SAP资产会计中常见的"AAPO176"错误提示,指出当交易类型(TType)与业务交易(Business Transaction)的"关联公司过账"(Post to Affiliated Company)标志不一致时,系统会拒绝过账。作者详细说明了该标志的作用机制,并提供了四种解决方案:修正交易类型使用、匹配正确的业务交易、调整系统配置或建立映射关系。文章还通过实际案例展示了配置错误对集团合并报表的影响,并附带了用于检查配置一致性的ABAP脚本。该错误通常

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 392

【rCore OS 开源操作系统】Rust 智能指针

在 Rust 中,“智能指针”是指那些实现了**特定智能行为**的指针类型。这些智能行为通常包括**内存管理**、**生命周期跟踪**以及**所有权转移等**。

碳基蒟蒻Serio的博客 1203

手把手教你学Simulink--基于微电网的建模与仿真场景实例:独立运行模式下微电网的能量管理系统设计

本文详细介绍了使用Simulink对独立运行微电网能量管理系统进行建模与仿真的完整流程。主要包括:系统结构设计(分布式能源、储能系统、负荷等模块)、建模步骤(从创建项目到实现能量管理策略)、仿真设置与结果分析。通过建立基于规则的控制逻辑和优化调度算法,实现微电网的自主运行和能量优化管理。文章还提供了参数优化和多目标改进建议,为新能源和智能电网领域的研究与应用提供了实用指导。

MHD0815的博客 8582

点云去噪:基于点云拟合的方法

点云处理是计算机视觉中的重要任务之一,而点云去噪是点云处理的关键步骤之一。在实际应用中,由于采集设备的噪声、运动估计误差或者环境干扰等因素,点云数据中常常包含有噪声点,这些噪声点会对后续的点云分析和处理造成不良影响。一种简单的方法是计算点到拟合曲面的距离,并将距离超过某个阈值的点定义为噪声点,进行过滤。一种简单的方法是计算点到拟合曲面的距离,并将距离超过某个阈值的点定义为噪声点,进行过滤。该方法通过拟合点云数据的曲面模型,对噪声点进行识别和过滤,从而得到更加干净的点云数据。

AuSwift的博客 638

【Rust中的智能指针】

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

m0_37719524的博客 1233

05 - GRACE数据处理-球谐展开与球谐综合

GRACE数据处理-球谐展开和综合前面在介绍GRACE相关理论的时候提到过下面的公式,从公式形式上可以看出,面密度变化和球谐系数(CS)之间是能够相互转换的,那这个转化的过程可以称为球谐展开,简单理解就是将全球网格数据转化为球谐系数的过程。而球谐综合可以看作是球谐展开的逆过程,利用球谐系数计算到全球格网分布。

weixin_43339605的博客 1050

Rust学习(七):智能指针

作为一种编程语言,Rust中最常见的指针类型就是引用,而引用只是一种普通指针,除引用数据之外,没有其他功能。为了更方便的处理复杂的结构数据,有必要在开始我们的算法之旅前,介绍Rust中智能指针的概率,当然,这里我们只会简单的介绍一些常用的智能指针,如果大家对此感到困惑,或者是想进一步深入的学习智能指针的设计哲学,建议阅读其Rust学习资料(doge)。智能指针是一种数据结构,其行为类似于指针,含有元数据,在大部分情况下拥有数据的所有权,提供内存管理或绑定等附加功能,如管理文件句柄和网络链接。

2301_77286822的博客 1190

操作系统实验一到实验九合集(哈工大李治军)

操作系统实验一到实验九合集(哈工大李治军) 有详细代码及注释,程序已在本地测试,均能跑通

leoabcd12的博客 5万+

Agentic AI应用架构师如何提升AI应用的灵活性

可扩展性(Scalability):快速添加新功能或扩展任务范围(如Agent从“客服”扩展到“供应链管理”);可修改性(Modifiability):调整Agent的决策逻辑或动作策略,无需重构整个系统;鲁棒性(Robustness):在环境异常或数据噪声下保持性能稳定;自适应(Self-Adaptation):自主学习新场景,无需人工干预。状态空间(S):Agent能感知的所有内部/外部状态(如用户需求、环境数据);动作空间(A):Agent能执行的所有动作(如调用工具、发送消息);

项目管理的博客 579

Rust学习之智能指针

在 Rust 中,最常见的指针类型是引用,引用本身指向某个值,不会造成性能上的额外损耗。而智能指针比引用有更复杂的数据结构,包含比引用更多的信息,例如元数据,当前长度,最大可用长度等。引用和智能指针的另一个不同在于前者仅仅是借用了数据,而后者往往可以拥有它们指向的数据。智能指针往往是基于结构体实现,它与我们自定义的结构体最大的区别在于它实现了Deref和DropDeref*TDrop动态字符串String和动态数组可以将值分配到堆上)、Rc(引用计数类型,允许多所有权存在)、Ref和。

2301_79967122的博客 947

深入解析机器人软件开发中的核心:状态机管理(FSM)—— 理论、实践与优化

状态机(FSM)是机器人软件开发中管理复杂行为逻辑的核心工具,广泛应用于导航、任务执行、故障处理等场景。本文系统探讨状态机的基础理论(定义、要素)、主流设计模式(经典FSM、分层状态机HSM、行为树BT),以及工业级实现方法(代码架构、线程安全、调试技巧)。通过移动机器人导航和机械臂任务执行的案例,分析分层状态机的实际应用,并总结常见陷阱(如状态爆炸、阻塞操作)与优化策略(异步化、事件过滤)。

郑伟强dev的专栏 292

Rust——智能指针

Rust智能指针

JAN6055的博客 2321

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Rust 智能指针深入浅出

《Rust智能指针全面解析》摘要: Rust智能指针是管理内存的高级工具,兼具指针功能和额外管理能力。主要类型包括:Box<T>用于单一所有权堆分配;Rc<T>实现单线程引用计数共享;RefCell<T>提供内部可变性;Arc<T>支持线程安全共享;Mutex<T>确保线程间安全修改。智能指针通过Deref和Drop trait实现解引用和资源清理,可组合使用(如Rc<RefCell<T>>或Arc<Mutex<

萧曳丶 956

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Rust 智能指针,让人省心

Rust 智能指针是所有权系统的 延伸,记住了!

码刀攻城 1410

Statistics and Machine Learning Toolbox

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

Rust从入门到精通之进阶篇:16.智能指针

你可以通过实现Deref和Dropvalue: T,println!("创建智能指针 {}", name);("释放智能指针 {}", self.name);write!println!println!*a += 1;// 使用 DerefMutprintln!("修改后: a = {}", a);Box<T>用于在堆上分配数据Rc<T>用于单线程环境中的共享所有权RefCell<T>用于单线程环境中的内部可变性Arc<T>

深耕大数据、BI 二次开发、Python与AI全栈工程;记录技术实战,也探索投资、创业、出海与技术人的第二曲线 1049

Rust 智能指针详解

Rust智能指针摘要(150字) Rust智能指针是内存管理核心工具,包括: Box<T>:堆分配,所有权唯一,用于递归类型/大数据转移 Rc<T>/Weak<T>:单线程引用计数,Weak解决循环引用 RefCell<T>:运行时借用检查实现内部可变性 Arc<T>:线程安全引用计数,多线程共享数据基础 Mutex<T>/RwLock<T>:线程同步,保护共享可变数据 组合模式常见: 单线程:Rc<RefCell&l

本博客分享软硬件一体化开发实战。硬件涵盖 PCB 设计、STM32 等 MCU 底层开发;软件包含 C++、Rust,Qt/QML、PyQt、Slint、TouchGFX、LVGL 各类 GUI 框架。方便软硬件开发者查阅学习。欢迎关注! 1525

【Rust】——通过Deref trait将智能指针当作常规引用处理

🎯追踪指针的值 🎯像引用一样使用Box 🎯自定义智能指针 🎯通过实现Deref trait 将某一类型像引用一样处理 🎯函数和方法的隐式Deref强制转换 🎯Deref强制转换如何与可变交互

shsjssnn的博客 2432

Rust 学习笔记——智能指针

https://doc.rust-lang.org/book/ch15-00-smart-pointers.html 智能指针是一种想指针一样的行为且具有其他能力的数据结构(Smart pointers, on the other hand, are data structures that not only act like a pointer but also have additional metadata and capabilities.)在 Rust 中,智能指针和引用最大的区别在于:智能指.

黄先生的博客 1031

Rust权威指南之智能指针

本文来源于阅读《Rust权威指南》第十五章:智能指针的读书笔记。快速了解Rust中Box、Rc、RefCell和Weak的相关知识。

学习和工作总结,共勉! 1821

Rust 学习笔记:Deref trait

Rust 学习笔记:Deref trait

ProgramNovice的博客 1010

Rust学习笔记(中)

笔记的内容主要参考与《Rust 程序设计语言》,一些也参考了《通过例子学 Rust》和《Rust语言圣经》。Rust学习笔记分为上中下,其它两个地址在我们可以使用泛型为像函数签名或结构体这样的项创建定义,这样它们就可以用于多种不同的具体数据类型。如下图,两个只在名称和签名中类型有所不同的函数,可以利用泛型优化它们。println!// 这里会报错largestprintln!println!选择T。

Fishermen_sail的博客 1351
上一篇: Rust 学习笔记:Deref trait
下一篇: Rust 学习笔记:Rc<T>
UestcXiye
博客等级 码龄8年 9028粉丝 1306原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UestcXiye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值