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

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 为弱引用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/908529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript ES6 解构:优雅提取数据的艺术

JavaScript ES6 解构&#xff1a;优雅提取数据的艺术 在 JavaScript 的世界中&#xff0c;ES6&#xff08;ECMAScript 2015&#xff09;的推出为开发者带来了许多革命性的特性&#xff0c;其中“解构赋值”&#xff08;Destructuring Assignment&#xff09;无疑是最受欢迎的功…

Shell 命令及运行原理 + 权限的概念(7)

文章目录 Shell 命令以及运行原理&#xff08;4-1.22.08&#xff09;Linux权限的概念1. 什么是权限2. 认识人&#xff08;普通用户&#xff0c;root用户&#xff09;以及两种用户的切换认识普通用户和root用户两种用户之间的切换指令提权 3. 文件的属性解析 权限属性指令ll显示…

以智能管理为基础,楼宇自控打造建筑碳中和新路径

在全球气候变化的严峻形势下&#xff0c;“碳中和”已成为各国发展的重要战略目标。建筑行业作为能源消耗与碳排放的“大户”&#xff0c;其运行阶段的能耗占全社会总能耗近40%&#xff0c;碳排放占比与之相当&#xff0c;实现建筑碳中和迫在眉睫。传统建筑管理模式下&#xff…

Python爬虫实战:研究Hyper 相关技术

一、项目概述 本项目展示了如何结合 Python 的异步编程技术与 Hyper 框架开发一个高性能、可扩展的网络爬虫系统。该系统不仅能够高效地爬取网页内容,还提供了 RESTful API 接口,方便用户通过 API 控制爬虫的运行状态和获取爬取结果。 二、系统架构设计 1. 整体架构 系统采…

html 滚动条滚动过快会留下边框线

滚动条滚动过快时&#xff0c;会留下边框线 但其实大部分时候是这样的&#xff0c;没有多出边框线的 滚动条滚动过快时留下边框线的问题通常与滚动条样式和滚动行为有关。这种问题可能出现在使用了自定义滚动条样式的情况下。 注意&#xff1a;使用方法 6 好使&#xff0c;其它…

【Linux】Ubuntu 创建应用图标的方式汇总,deb/appimage/通用方法

Ubuntu 创建应用图标的方式汇总&#xff0c;deb/appimage/通用方法 对于标准的 Ubuntu&#xff08;使用 GNOME 桌面&#xff09;&#xff0c;desktop 后缀的桌面图标文件主要保存在以下三个路径&#xff1a; 当前用户的桌面目录&#xff08;这是最常见的位置&#xff09;。所…

【自然语言处理】大模型时代的数据标注(主动学习)

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计E 个人总结 A 论文出处 论文题目&#xff1a;FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models发表情况&#xff1a;2023-EMNLP作者单位&#xff1a;浙江大…

【论文解读】DeepSeek-R1

文章目录 概览一、DeepSeek-R1-Zero&#xff1a;在 Base Model 上直接进行 RL&#xff08;一&#xff09;强化学习算法&#xff08;二&#xff09;奖励模型&#xff08;三&#xff09;数据构造&#xff08;四&#xff09;DeepSeek-R1-Zero 的性能、自我进化过程和 Aha Moment1.…

巴西医疗巨头尤迈Kafka数据泄露事件的全过程分析与AI安防策略分析

一、事件背景与主体信息 涉事主体:Unimed,全球最大医疗合作社,巴西医疗行业龙头企业,拥有约1500万客户。技术背景:泄露源于其未保护的Kafka实例(开源实时数据传输平台),用于客户与聊天机器人“Sara”及医生的实时通信。二、时间线梳理 时间节点关键事件描述2025年3月24…

软信天成:数据驱动型背后的人工智能,基于机器学习的数据管理

在数字化转型浪潮中&#xff0c;当代企业如同逆水行舟&#xff0c;不进则退。无数企业希望通过数字化转型捕获全新的市场机遇&#xff0c;改善财政状况&#xff0c;在未来市场竞争中占据一席之地。要想获得成功的数字化转型&#xff0c;关键因素在于具备可靠、及时的数据用以支…

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…

【Java学习笔记】StringBuilder类(重点)

StringBuilder&#xff08;重点&#xff09; 1. 基本介绍 是一个可变的字符串序列。该类提供一个与 StringBuffer 兼容的 API&#xff0c;但不保证同步&#xff08;StringBuilder 不是线程安全的&#xff09; 该类被设计用作 StringBuffer 的一个简易替换&#xff0c;用在字符…

计算机网络 | 1.2 计算机网络体系结构与参考模型

计算机网络体系结构与参考模型 目录 计算机网络体系结构与参考模型 【思维导图】 1、计算机的分层结构 1、为什么要分层&#xff1f; 2、什么是计算机网络体系结构 2、计算机网络协议、接口和服务 1&#xff09;协议&#xff1a; 2&#xff09;接口&#xff1a; 3…

微软的新系统Windows12未来有哪些新特性

在今年即将到来的重大设计升级中,苹果计划对其全线操作系统统一按年份命名,作为另一巨头微软的win12还远吗?win11和win10是微软现在正在用的主流版本,win11系统发布于2021年6月24日,win10系统发布于2015年7月29日。预计win12尝鲜版可能在2025年下半年或明年。 尽管win12还…

制造业数智化卡在知识断层?R²AIN SUITE AI知识管理打通关键经络

在一家工厂里&#xff0c;工程师正面临棘手难题——某机器异常振动的处理方案。他的笔记本记录着三年前类似案例的解决方案&#xff0c;但翻查半小时仍未找到关键参数。与此同时&#xff0c;工厂的碳排放监控系统显示&#xff0c;因设备停机导致的额外能源损耗已使产线碳强度有…

构造数列中的常见变形总结

前情概要 针对高考中构造数列的常见变形做一总结,便于梳理思路,提升思维。 类型Ⅰ: 形如 a n + 1 = p ⋅ a n + q a_{n+1}=p\cdot a_n+q an+1​=p⋅an​+q, p , q p,q p,q为常数,即 a n + 1 = f ( a n ) a_{n+1}=f(a_n) an+1​=f(an​),构造变形方向: 其一: a n…

全国县域统计年鉴PDF-Excel电子版-2022年

全国县域统计年鉴PDF-Excel电子版-2022年.ziphttps://download.csdn.net/download/2401_84585615/89784662 https://download.csdn.net/download/2401_84585615/89784662 《中国县域统计年鉴》是一部全面反映中国县域社会经济发展状况的资料性年鉴。自2014年起&#xff0c;该年…

81 实战一:给root目录扩容

添加一块100G硬盘 vgextend centos /dev/sdb1 /dev/sdc lvextend -L +120G /dev/centos/root xfs_growfs /dev/centos/root df -h 看是否扩容成功 82 实战二:给swap空间扩容 添加一块20G硬盘 fdisk -l 可以看到新添加的硬盘 vgextend centos /dev/sdd …

实现购物车微信小程序

实现一个微信小程序购物车页面&#xff0c;包含以下功能&#xff1a; 需求说明&#xff1a; 商品列表&#xff1a;显示商品名称、价格、数量加减按钮&#xff0c;支持修改商品数量&#xff08;数量≥1&#xff09;。 全选 / 反选功能&#xff1a;顶部 “全选” 复选框&#…

R语言使用随机过采样(Random Oversampling)平衡数据集

随机过采样&#xff08;Random Oversampling&#xff09;是一种用于平衡数据集的技术&#xff0c;常用于机器学习中处理类别不平衡问题。当某个类别的样本数量远少于其他类别时&#xff08;例如二分类中的正负样本比例悬殊&#xff09;&#xff0c;模型可能会偏向多数类&#x…