rust学习十五.5、引用循环和内存泄露

news/2025/1/9 9:24:17/文章来源:https://www.cnblogs.com/lzfhope/p/18655762

这个章节主要是为了引出弱引用这个奇怪的概念。

说实在,这个没有什么太好写的,因为内容比较晦涩难懂!

 

在其它语言中,也常常存在所谓循环引用问题,和大部分问题一样,在其它语言中这些基本上都不是问题。但是在rust中,这是一个致命的问题。

 

例如有a,b两个点,a指向b,b指向a。

如果根据截止当前的知识(所有权、一个数据也可以有多个所有者),那么rust可能无法释放a所实际指向的数据,或者是因为循环递归导致堆栈溢出。

或者其实我们也没有必要知道为什么,只要知道结论即可,毕竟如果我们不看编译器是怎么写的。所以,有的时候就是看到了概念,看到了例子也是难以理解。

 

这些都需要借助于一些概念和例子来理解。

堆栈溢出示例(来自原书):

use crate::List::{Cons, Nil};
use std::cell::RefCell;
use std::rc::Rc;#[derive(Debug)]
enum List {Cons(i32, RefCell<Rc<List>>),Nil,
}impl List {fn tail(&self) -> Option<&RefCell<Rc<List>>> {match self {Cons(_, item) => Some(item),Nil => None,}}
}fn main() {let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));println!("a initial rc count = {}", Rc::strong_count(&a));println!("a next item = {:?}", a.tail());let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));println!("a rc count after b creation = {}", Rc::strong_count(&a));println!("b initial rc count = {}", Rc::strong_count(&b));println!("b next item = {:?}", b.tail());if let Some(link) = a.tail() {*link.borrow_mut() = Rc::clone(&b);}println!("b rc count after changing a = {}", Rc::strong_count(&b));println!("a rc count after changing a = {}", Rc::strong_count(&a));// Uncomment the next line to see that we have a cycle;// it will overflow the stack// println!("a next item = {:?}", a.tail());
}

 

rust在做匹配的时候,会不断找尾巴,结果循着尾巴一直找.....

 

rust推出一个新的概念:弱引用(weak reference)

所谓弱引用,即指向某个数据,但是这种引用不会产生所有权方面的问题,就如同大部分其它语言那样的美好。

 

一、重要概念

Rc::downgrade
Rc::downgrade 会将 weak_count 加 1,同时返回Weak<T>指针
这个函数用于构建弱引用
 
Weak::upgrade()
Weak<T> 实例的 upgrade 方法,这会返回 Option<Rc<T>>
 

二、例子

书上例子很完善,稍微修改了下:

use std::cell::RefCell;
use std::rc::{ Rc, Weak };#[derive(Debug)]
struct Node {value: i32,parent: RefCell<Weak<Node>>,children: RefCell<Vec<Rc<Node>>>,
}fn main() {look_weak_ref();
}fn look_weak_ref() {let leaf = Rc::new(Node {value: 3,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![]),});println!("leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf));{println!("------------------------------------------------------------------------------");let branch = Rc::new(Node {value: 5,parent: RefCell::new(Weak::new()),children: RefCell::new(vec![Rc::clone(&leaf)]),});*leaf.parent.borrow_mut() = Rc::downgrade(&branch);println!("branch strong = {}, weak = {}",Rc::strong_count(&branch),Rc::weak_count(&branch));println!("leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf));println!("------------------------------------------------------------------------------");}println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());println!("leaf strong = {}, weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf));
}

 

三、小结

如果我们成心构建导致堆栈溢出的死循环,还是可以的,书上也有这个例子。

但rust提供了可以避免这个的方法,毕竟这种需求还是不鲜见的!

 

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

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

相关文章

腾讯云轻量服务器搭建彩虹聚合 DNS 聚合管理系统教程

彩虹聚合 DNS 管理系统具备诸多实用功能,其中包括 SSL 证书申请与自动部署功能,它能够从多个渠道申请 SSL 证书,像 Lets Encrypt 等,并自动将证书部署到各式各样的面板、云服务商以及服务器等环境中,同时还支持 CNAME 代理功能,为域名管理和安全访问提供了有力保障。 一、…

Django 3 Web应用开发实战PDF、EPUB免费下载

以DjangoWeb项目开发为主线,从源码的角度,深入剖析Django3企业级开发技术。适读人群 :适合有一定Python基础的Web开发人员阅读,也可用作培训机构和大中专院校相关专业的教学参考书。 以DjangoWeb项目开发为主线,从源码的角度,深入剖析Django3企业级开发技术。电子版仅供预…

网络流23题做题笔记

省流:我没意见link【模板】网络最大流 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; using ll=long long; const int N=1e5+5; const ll inf=1e16+5; int n,m,S,T,head[N],idx=1; struct edge{int t…

LAS点云如何转换为3DTiles格式?用这款免费工具轻松搞定!

概述 随着数字孪生和三维城市模型技术的迅速发展,点云数据的使用越来越广泛。而LAS格式作为常见的点云数据存储格式,因其精确度高、数据丰富,成为了地形测绘、建筑建模等领域的主流数据源。然而,如何将这些庞大的LAS点云数据转换成适用于Web端展示的3DTiles格式,成了许多开…

linux系统串口终端软件显示异常解决方法,触觉智能出品

分享linux系统串口终端软件显示异常解决方法,以xshell软件为例本文介绍linux系统串口终端软件显示异常解决方法,以xshell软件为例。使用触觉智能的Purple Pi R1双网口开发板演示,内置双核A7 1.2Ghz处理器,支持WiFi与丰富GPIO拓展,是嵌入式新人入门学习的高性价比开发板! …

SecureFX for Mac FTP/SSH传输工具

SecureFX for Mac FTP/SSH传输工具 SecureFX mac破解版是一款Mac平台的FTP/SSH传输工具。SecureFX for Mac支持三种文件传输协议:FTP、SFTP 和 FTP over SSH2。它可以提供安全文件传输。无论您连接的是任何一种操作系统的服务器,它都能提供安全的传输服务。它主要用于Linux操…

Debian 11/12一键更换国内系统源

有时候买了国内的服务器,更新系统或者安装软件速度相当慢,这时候我们可以将系统源一键更换为国内的源,速度就会快很多!一、备份现有apt源配置 cp -a /etc/apt/sources.list /etc/apt/sources.list.bak二、替换为其他apt源 Debian11 1、清华源 这是一条命令,全部复制后,直…

创建销售订单BAPI报错,SLS_LORD 033

只提示一个凭证 不能保存的消息,没有任何提示及字段信息 跟消息断点发现是被增强卡住了

用 Modbus 软件配置 Modbus tcp 转 ETHERCAT 步骤

在工业自动化控制系统中,常常会遇到不同协议设备集成的需求。例如,部分设备采用 Modbus tcp 协议进行通信,而另一些设备则基于 ETHERCAT 协议运行。这种协议差异导致设备之间无法直接进行数据交互,严重影响了整个系统的协同工作和自动化程度。为解决这一问题,我们引入捷米…

pd虚拟机 [po] Parallels Desktop 20 激活 for Mac [jie] 安装教程【支持M芯片】

pd虚拟机 [po] Parallels Desktop 20 激活 for Mac [jie] 安装教程【支持M芯片】 Parallels Desktop 20 ,是一款Mac虚拟机软件,在搭载Apple M 系列芯片的任何 Mac 上运行 Windows,体验不同操作系统之间无缝集成。使用 Parallels Desktop 20 for Mac 体验 macOS 和 Windows 的…

【触想智能】什么是嵌入式工业一体机以及它的特点和应用领域分析

嵌入式工业一体机是一种集成了计算、控制、通信等功能的高度集成化设备。它在工业自动化领域中有着广泛的应用,为工厂生产、数据处理、监控和管理提供了全面的解决方案。下面是嵌入式工业一体机的定义、特点以及主要应用领域的具体介绍。一、嵌入式工业一体机的定义嵌入式工业…

VMware Fusion Pro 13 for Mac虚拟机软件

VMware Fusion Pro 13 for Mac虚拟机软件 VMware Fusion Pro for Mac,是一款mac虚拟机软件,跟Parallels Desktop一样,都可以让你的 Mac 同时运行一个或多个不同的操作系统。VMware Fusion Pro mac不仅能让你在Mac苹果电脑上运行Windows或Linux系统、使用非Mac平台的软件,而…