学习笔记八——内存管理相关

📘 目录

  1. 内存结构基础:栈、堆、数据段
  2. Rust 的内存管理机制(对比 C/C++、Java)
  3. Drop:Rust 的自动清理机制
  4. Deref:为什么 *x 能访问结构体内部值
  5. Rc:多个变量“共享一个资源”怎么办?
  6. Weak:如何打破 Rc 的循环引用?
  7. borrow_mut 和 downgrade 是什么意思?
  8. 👁 Rc / Weak / Deref / Drop 关系图
  9. 总结 & 使用建议

1️⃣ 内存结构基础

Rust 程序运行时,内存大致分为:

区域用途说明生命周期
存储函数调用的局部变量函数调用期间
存储动态分配的大对象显式释放或自动释放
数据段静态变量、全局变量等程序运行全过程

2️⃣ Rust 的内存管理机制

  • Rust 不靠垃圾回收器
  • 通过“所有权 + 借用”系统管理内存
  • 编译时就能判断内存是否正确释放
fn main() {let s = String::from("hello");let t = s;// println!("{}", s); // ❌ 错误:s 的所有权已经被转移给 t
}

3️⃣ Drop:变量作用域结束自动释放

你可以实现 Drop trait,在变量被释放时自动执行逻辑。

struct Connection;impl Drop for Connection {fn drop(&mut self) {println!("连接关闭!");}
}fn main() {let _conn = Connection;println!("连接中…");
}
// 输出:连接中… ➤ 连接关闭!

4️⃣ Deref:让结构体支持 *x

Rust 中 *x 默认是用于“解引用”指针或引用。如果你想让自己写的结构体也支持 *x,就需要实现 Deref

use std::ops::Deref;struct MyBox<T>(T);impl<T> Deref for MyBox<T> {type Target = T;fn deref(&self) -> &Self::Target {&self.0 // 访问结构体里的第一个字段}
}

5️⃣ Rc:多个变量想“共同拥有”一个资源?

默认变量所有权不能共享:

let a = String::from("hi");
let b = a; // a 不再拥有字符串

如果你希望多个变量共享一个资源(比如多个节点共享同一根节点),可以用:

use std::rc::Rc;let a = Rc::new(String::from("hello"));
let b = Rc::clone(&a);  // ✅ 不是深拷贝,只是计数 +1
let c = Rc::clone(&a);

6️⃣ Weak:如何解决 Rc 的循环引用?

🌀 什么是循环引用?

a → b → a   // 永远互相指着,永远无法释放

✅ Weak 是什么?

  • Rc<T>:是“强引用”,决定资源释放
  • Weak<T>:是“弱引用”,不会影响资源生命周期

7️⃣ borrow_mut 和 downgrade 是什么意思?

🔹 borrow_mut 是什么?

当你使用 RefCell<T> 来包裹一个值时,可以在运行时借用它的可变引用。

use std::cell::RefCell;let x = RefCell::new(5);
*x.borrow_mut() = 10;  // ✅ 可变借用并修改

解释:

  • .borrow_mut():是 RefCell 提供的方法
  • 它返回一个可变引用,类似于 &mut T,但是在运行时检查是否有冲突

📌 注意:不能同时有可变和不可变借用,否则运行时会 panic。


🔹 downgrade 是什么?

Rc::downgrade(&rc) 是把一个 Rc<T> 强引用变成 Weak<T> 弱引用。

let strong = Rc::new(String::from("Rust"));
let weak = Rc::downgrade(&strong); // 不增加引用计数

可以用 weak.upgrade()Weak 转回 Rc,如果值还活着,就返回 Some(Rc),否则是 None


🧪 示例:父子节点用 Weak 打破循环引用

use std::rc::{Rc, Weak};
use std::cell::RefCell;struct Node {value: i32,parent: RefCell<Option<Weak<Node>>>,  // 👈 防止循环引用children: RefCell<Vec<Rc<Node>>>,
}fn main() {let parent = Rc::new(Node {value: 1,parent: RefCell::new(None),children: RefCell::new(vec![]),});let child = Rc::new(Node {value: 2,parent: RefCell::new(Some(Rc::downgrade(&parent))),  // 🔥 不增加计数children: RefCell::new(vec![]),});parent.children.borrow_mut().push(child.clone());// 程序结束时能正确释放所有节点
}

8️⃣ 👁 Rc / Weak / Deref / Drop 关系图

   ┌────────────┐│ Rc<T>      │◄─────┐└────────────┘      │ Rc::clone()▲              ││              ││ Rc::downgrade│▼              │┌────────────┐      ││ Weak<T>    │────┐ │└────────────┘    │ ││            │ ││ upgrade()  ▼ ▼│       ┌─────────┐│       │ *x 解引用│(Deref)▼       └─────────┘drop()(当 Rc 引用数为 0 自动触发)

✅ 总结 & 建议

工具功能说明典型使用场景
Rc<T>多个所有者,共享资源单线程共享结构,如树结构
Weak<T>不增加计数,防止循环引用父指向子用 Rc,子指向父用 Weak
RefCell<T>运行时可变借用检查单线程内部可变性
borrow_mut在 RefCell 中获取可变引用RefCell<i32>.borrow_mut()
downgrade将 Rc 转为 Weak,不影响引用计数避免结构间强依赖
Deref让自定义类型也能用 *x 访问内部值智能指针封装
Drop离开作用域时自动释放资源自动释放连接、缓存等

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

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

相关文章

ReliefF 的原理

&#x1f31f; ReliefF 是什么&#xff1f; ReliefF 是一种“基于邻居差异”的特征选择方法&#xff0c;用来评估每个特征对分类任务的贡献大小。 它的核心问题是&#xff1a; “我怎么知道某个特征是不是重要&#xff1f;是不是有能力把不同类别的数据区分开&#xff1f;” 而…

​asm汇编源代码之-汉字点阵字库显示程序源代码下载​

汉字点阵字库显示程序 源代码下载 文本模式下显示16x16点阵汉字库内容的程序(标准16x16字库需要使用CHGHZK转换过后才能使用本程序正常显示) 本程序需要调用file.asm和string.asm中的子程序,所以连接时需要把它们连接进来,如下 C:\> tlink showhzk file string 调用参…

【已更新完毕】2025泰迪杯数据挖掘竞赛B题数学建模思路代码文章教学:基于穿戴装备的身体活动监测

基于穿戴装备的身体活动监测 摘要 本研究基于加速度计采集的活动数据&#xff0c;旨在分析和统计100名志愿者在不同身体活动类别下的时长分布。通过对加速度数据的处理&#xff0c;活动被划分为睡眠、静态活动、低强度、中等强度和高强度五类&#xff0c;进而计算每个志愿者在…

Ubuntu24.04装机安装指南

文章目录 Ubuntu24.04装机安装指南一、分区说明二、基础软件三、使用fcitx5配置中文输入法四、安装搜狗输入法【**不推荐**】1. 安装fcitx2. 安装输入法 五、禁用/home目录下自动生成文件夹六、更新软件源1. 针对**新配置方式**的清华源替换方法2. 针对**老配置方式**的清华源替…

互联网三高-数据库高并发之分库分表ShardingJDBC

1 ShardingJDBC介绍 1.1 常见概念术语 ① 数据节点Node&#xff1a;数据分片的最小单元&#xff0c;由数据源名称和数据表组成 如&#xff1a;ds0.product_order_0 ② 真实表&#xff1a;再分片的数据库中真实存在的物理表 如&#xff1a;product_order_0 ③ 逻辑表&#xff1a…

BM25、BGE以及text2vec-base-chinese的区别

BM25、BGE以及text2vec-base-chinese的区别 BM25 原理:BM25(Best Matching 25)是一种基于概率检索模型的算法,它通过考虑查询词与文档之间的匹配程度、文档的长度等因素,来计算文档对于查询的相关性得分。具体来说,它会给包含查询词次数较多、文档长度适中的文档更高的分…

Python中try用法、内置异常类型与自定义异常类型拓展

目录 try介绍与语法格式try具体使用案例except的异常类型简介案例内置的常见异常类型自定义异常类型继承关系用途 注意事项 try介绍与语法格式 在 Python 里&#xff0c;try 语句主要用于异常处理&#xff0c;其作用是捕获并处理代码运行期间可能出现的异常&#xff0c;避免程…

【第41节】windows的中断与异常及异常处理方式

目录 一、中断与异常处理 1.1 中断与异常 1.2 IDT 1.3 异常的概念 1.4 异常分类 二、windows异常处理方式 2.1 概述 2.2 结构化异常处理 2.3 向量化异常处理之VEH 2.4 向量化异常处理之VCH 2.5 默认的异常处理函数 2.6 如何手动安装 SEH 节点 2.7 异常处理的优先级…

分布式日志治理:Log4j2自定义Appender写日志到RocketMQ

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

【HTML】html文件

HTML文件全解析&#xff1a;搭建网页的基石 在互联网的广袤世界里&#xff0c;每一个绚丽多彩、功能各异的网页背后&#xff0c;都离不开HTML文件的默默支撑。HTML&#xff0c;即超文本标记语言&#xff08;HyperText Markup Language&#xff09;&#xff0c;作为网页创建的基…

oracle命令上下左右键无法使用如何解决?

1、问题如图 2、解决办法 (1) 安装readline yum -y install readline* &#xff08;2&#xff09;安装 rlwrap ##下载 wget http://files.cnblogs.com/files/killkill/rlwrap-0.30.tar.gz.zip ##解压 tar -xzvf rlwrap-0.30.tar.gz.zip ##编译安装 ./configure make &&…

vue事假机制都有哪些

Vue 的事件机制主要包含以下几种类型和方式&#xff0c;可以分为组件内部事件、父子组件通信事件、原生 DOM 事件封装、修饰符增强等&#xff0c;下面详细分类介绍&#xff1a; 一、DOM 事件绑定&#xff08;最基础的事件&#xff09; 使用 v-on&#xff08;或简写 &#xff0…

系统编程2(消息队列)

⦁ 消息队列概念 Linux系统中消息队列&#xff08;Message Queue&#xff09;是进程间通信的一种方式&#xff0c;这种通信机制的好处是可以传输指定类型(用户可以自行定义)的数据&#xff0c;相同类型的数据根据到达顺序在队列中进行排队。 当然&#xff0c;不同类型的数据不…

Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二)

Pytorch深度学习框架60天进阶学习计划 - 第41天&#xff1a;生成对抗网络进阶&#xff08;二&#xff09; 7. 实现条件WGAN-GP # 训练条件WGAN-GP def train_conditional_wgan_gp():# 用于记录损失d_losses []g_losses []# 用于记录生成样本的多样性&#xff08;通过类别分…

python 微博爬虫 01

起因&#xff0c; 目的: ✅下载单个视频&#xff0c;完成。✅ 获取某用户的视频列表&#xff0c;完成。剩下的就是&#xff0c; 根据视频列表&#xff0c;逐个下载视频&#xff0c;我没做&#xff0c;没意思。获取视频的评论&#xff0c;以后再说。 关键点记录: 1. 对一个视…

Servlet、HTTP与Spring Boot Web全面解析与整合指南

目录 第一部分&#xff1a;HTTP协议与Servlet基础 1. HTTP协议核心知识 2. Servlet核心机制 第二部分&#xff1a;Spring Boot Web深度整合 1. Spring Boot Web架构 2. 创建Spring Boot Web应用 3. 控制器开发实践 4. 请求与响应处理 第三部分&#xff1a;高级特性与最…

vue中根据html动态渲染内容2.0

上次使用的是p标签用的contenteditable代替的可编辑的input&#xff0c;最后实现还是选择了用el-input的textarea方式。 一开始考虑的是需要根据用户输入自动撑开输入框&#xff0c;所以选择了p标签可编辑。 最后发现还是el-input会更好一点&#xff0c;只不过需要处理输入框撑…

CentOS 系统磁盘扩容并挂载到根目录(/)的详细步骤

在使用 CentOS 系统时&#xff0c;经常会遇到需要扩展磁盘空间的情况。例如&#xff0c;当虚拟机的磁盘空间不足时&#xff0c;可以通过增加磁盘容量并将其挂载到根目录&#xff08;/&#xff09;来解决。以下是一个完整的操作流程&#xff0c;详细介绍了如何将新增的 10G 磁盘…

LINUX基础 [二] - Linux常见指令

目录 &#x1f4bb;前言 &#x1f4bb;指令 &#x1f3ae;ls指令 &#x1f3ae;pwd指令 &#x1f3ae;whoami指令 &#x1f3ae;cd指令 &#x1f3ae;clear指令 &#x1f3ae;touch指令 &#x1f3ae;mkdir指令 &#x1f3ae;rmdir指令 &#x1f3ae;rm指令 &#…

基于php的成绩分析和预警与预测网站(源码+lw+部署文档+讲解),源码可白嫖!

摘要 人类现已迈入二十一世纪&#xff0c;科学技术日新月异&#xff0c;经济、资讯等各方面都有了非常大的进步&#xff0c;尤其是资讯与网络技术的飞速发展&#xff0c;对政治、经济、军事、文化、教育等各方面都有了极大的影响。 利用电脑网络的这些便利&#xff0c;发展一套…