【Rust中级教程】1.5. 内存 Pt.3:深入探究Rust堆内存底层实现
1.5 内存 Pt.3深入探究Rust堆内存底层实现1.5.1. 堆内存(Heap)Heap意味着混乱而stack则相对比较整齐。Heap是一个内存池并没有绑定到当前程序的调用栈而stack绑定到当前程序的调用栈。Heap是为在编译时没有已知大小的类型准备的而stack上的数据在编译时大小必须已知。如图heap上的数据存放的位置和自身的大小都是不一定的比较常见的情况是stack有一个指针指向heap上的数据。什么叫在编译时大小不已知- 一些类型会随着时间变大或变小例如String、VecT。这些类型本身是Sized的在栈上是固定大小的结构体但它们拥有的缓冲区在堆上可以改变大小。- 另一些类型的大小不会改变但是无法告诉编译器需要分配多少内存- 另一个例子是trait对象详见 【Rust自学】19.5.4. 动态大小和和Sizedtrait它允许程序员模拟一些动态语言的特性——将多个类型放进一个容器- 真正的动态大小类型(dynamically sized types简称DST)——也叫unsized types——包括切片如str、[T]以及trait对象如dyn Trait。String和VecT本身不是DST它们是通过一个Sized句柄来管理堆上动态大小数据的。Heap允许你显示地分配连续的内存块。当这么做时你就会得到一个指针它指向内存开始的地方。Heap中的值会一直有效直到你对它显式地释放。如果你想让值活得比当前函数frame详见 1.4. 内存 Pt.2的生命周期还长就很有用。如果值是函数的返回值那么调用函数可以在它的stack上留一些空间给被调用函数让它把值在返回前写入进去。1.5.2. 堆内存与线程安全如果想要把值送到另一个线程当前线程可能根本无法与那个线程共享stack frames你就可以把它存在堆内存上。因为函数返回时堆内存上的分配不会消失所以你在一个地方为值分配内存把指向它的指针传给另一个线程就可以让那个线程安全地操作于这个值。换一种说法当你分配堆内存时结果指针会有一个无约束的生命周期你的程序想让数据活多久都行。1.5.3. 堆内存的交互机制堆内存上的变量必须通过指针访问。看个例子fn main(){ let a: i32 40; // Stack let b: Boxi32 Box::new(60); // Heap let result a b; let result a *b; println!({} {} {}, a, b, result); }输出error[E0277]: cannot add Boxi32 to i32 -- src/main.rs:4:20 | 4 | let result a b; | ^ no implementation for i32 Boxi32 | help: the trait AddBoxi32 is not implemented for i32 help: consider dereferencing here | 4 | let result a *b; | a是i32类型放在栈内存上的b是Boxi32类型放在堆内存上的但是这么写肯定是有问题的问题出在let result a b;上堆内存上的数据必须通过指针来访问b是指针a是数字两者类型不同肯定不能相加。所以我们删掉这句话把原代码改成fn main(){ let a: i32 40; // Stack let b: Boxi32 Box::new(60); // Heap let result a *b; println!({} {} {}, a, b, result); }let result a *b;通过*对b进行了解引用把指针指向的值60取出来了。输出40 60 100Rust与堆内存的交互方式Rust里与堆内存交互的主要方式就是BoxT类型。当我们使用Box::new函数创建类型为BoxT的实例时值传进Box::new函数的参数就会被放在堆内存上返回的(BOxT)就是指向堆内存上的指针。当Box被丢弃时内存就会被释放。如果忘记释放堆内存就会导致内存泄漏。但有时候程序员会故意让内存泄漏例如有一个只读的配置整个程序都需要访问它。这时候就可以通过Box::leak得到一个‘static引用从而显式地让其进行泄露。看个例子use std::mem::drop; fn main(){ let a Box::new(1); let b Box::new(1); let c Box::new(1); let result1 *a *b *c; drop(a); let d Box::new(1); let result2 *b *c *d; println!({} {}, result1, result2); }使用std::mem::drop函数可以手动释放我们讲讲这个程序的逻辑- 首先声明了变量a、b和c值都是存储在堆内存上的1Boxi32类型- 使用*对三个变量都进行解引用然后相加得到result1- 得到result1之后使用drop函数直接抛弃了a- 然后声明了变量d值是存储在堆内存上的1Boxi32类型- 使用对*三个变量(b、c和d)进行解引用然后相加得到result2- 打印出result1和result2我们用一张图来看看这个程序执行中内存的变化

相关新闻

【Rust中级教程】1.6. 内存 Pt.4:静态(static)内存与‘static生命周期标注

【Rust中级教程】1.6. 内存 Pt.4:静态(static)内存与‘static生命周期标注

1.6 内存 Pt.4:静态(static)内存与static生命周期标注 1.6.1. 静态(static)内存 static内存实际上是一个统称,它指的是程序编译后的文件中几个密切相关的区域。当程序执行的时候,这些区域会自动加载到内存里。 static内存里的值会在程序执行期…

2026/7/24 20:41:08 阅读更多 →
若依项目Linux生产环境治理:文件系统权限配置实战

若依项目Linux生产环境治理:文件系统权限配置实战

前言记得有一次,开发同事需要查看 application.yml 里的数据库连接配置,看完之后顺手按了上下键,不小心执行了上一条 vim application.yml,然后手滑按了几个键,保存退出了。等他反应过来,配置已经乱了&…

2026/7/24 20:41:08 阅读更多 →
AssetRipper终极指南:轻松提取Unity游戏资源的免费开源神器

AssetRipper终极指南:轻松提取Unity游戏资源的免费开源神器

AssetRipper终极指南:轻松提取Unity游戏资源的免费开源神器 【免费下载链接】AssetRipper GUI application to analyze game files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper 你是否曾经遇到过这样的困境?想要分析一个Unity…

2026/7/24 20:41:08 阅读更多 →

最新新闻

从“被生活推动”,进入“主动创造”。

从“被生活推动”,进入“主动创造”。

人生最大的转变,不是环境突然变好了,而是一个人从“反应模式”进入“创造模式”。很多人每天都很忙。 但忙完之后发现: 好像一直在处理事情。 却没有真正建设自己的生活。第一层:什么叫“被生活推动”? 被生活推动的人…

2026/7/24 20:48:09 阅读更多 →
企业全球化新闻发布选哪家?朝闻通海量媒体资源兼顾高效与真实

企业全球化新闻发布选哪家?朝闻通海量媒体资源兼顾高效与真实

时效性是新闻传播的核心内核,也是数字时代衡量品牌传播效率的关键标准。随着信息技术高速迭代,即时发布、快速触达成为新闻公关传播的基本要求。但行业长期存在一大核心矛盾:传播速度与内容精准难以兼顾。一味追求发布速度,极易出…

2026/7/24 20:48:09 阅读更多 →
周报6.21

周报6.21

小组周报小组成员: 陈思潼 汇报周期: 2026年6月17日—2026年6月21日一、本周计划 算法实现与实验验证 可见光与SAR融合目标检测的数据集,可见光与SAR分别使用YOLO系列模型5次重复实验 结果整理与问题分析 汇总实验结果二、本周进展 2.1 实验与…

2026/7/24 20:48:09 阅读更多 →
网络变压器怎么区分单口和双口?

网络变压器怎么区分单口和双口?

网络变压器怎么区分单口和双口? 最快有两招:一看料号里的口数数字,二数线圈图里"1CT:1CT"变压器组数——4 组单口、8 组双口 为什么要先区分单口和双口? 一个 RJ45 网口需要一组网络变压器,对应 4 对差分信…

2026/7/24 20:48:09 阅读更多 →
07.02.03.tiptop集成篇(4gl扩展功能 集成java:封装java的poi包设配4gl 案例 导入excle)

07.02.03.tiptop集成篇(4gl扩展功能 集成java:封装java的poi包设配4gl 案例 导入excle)

本页目录 1、案例2、测试 闲鱼DKLi1717&#xff1a; 引用POI包Excel批量处理 s_poi_excel.4gl 下载excle的模板到桌面anmt200.xlsx 案例 p_test.4fd <?xml version"1.0" encoding"UTF-8" ?> <ManagedForm gstVersion"22800" name…

2026/7/24 20:48:09 阅读更多 →
SDC命令详解:使用set_sense命令进行约束

SDC命令详解:使用set_sense命令进行约束

相关阅读 SDC命令详解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 目录 时钟极性 指定引脚、端口列表/集合 指定类型 指定正单调性 指定负单调性 指定停止传播 指定时钟脉冲 指定时钟列表/集合 指定时钟叶节点 Multicorner-Multim…

2026/7/24 20:47:09 阅读更多 →

日新闻

用Highcharts 创建可拖拽三维散点立方体3D图表

用Highcharts 创建可拖拽三维散点立方体3D图表

该案例基于Highcharts scatter3d 三维散点图实现空间立方体散点可视化&#xff0c;核心特色&#xff1a;三维 X/Y/Z 三轴空间&#xff0c;所有散点分布在 0~10 立方体空间内&#xff1b;散点使用径向渐变实现立体 3D 圆球质感&#xff1b;支持鼠标 / 触屏拖拽画布&#xff0c;…

2026/7/24 0:00:29 阅读更多 →
AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls:进程创建路径上的 DLL 入口

AppCertDlls&#xff1a;进程创建路径上的 DLL 入口 AppCertDlls 位于 HKLM\System\CurrentControlSet\Control\Session Manager\AppCertDlls。本文的程序功能是只读列出这个键在 64 位和 32 位注册表视图中的全部值&#xff0c;并显示每条值的来源、名称、类型和可安全显示的数…

2026/7/24 0:00:29 阅读更多 →
我的编程之路:第一篇博客

我的编程之路:第一篇博客

大家好&#xff0c;我是一名编程初学者&#xff0c;同时这也是我编程学习之路上的第一篇博客。在这里&#xff0c;我想要向大家介绍我的一些想法和规划。a.自我介绍我是一个刚刚接触编程的新手&#xff0c;目前在学习c语言&#xff0c;我对编程世界充满了强烈的好奇。当然&…

2026/7/24 0:00:29 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中&#xff0c;我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源&#xff0c;还是配置文件、证书等&#xff0c;都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下&#xff0c;但这…

2026/7/24 3:59:20 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP&#xff08;轻量级目录访问协议&#xff09;作为企业级身份认证的黄金标准&#xff0c;已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时&#xff0c;发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/24 1:23:39 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”&#xff0c;而是以可解释、可审计、可迭代的方式&#xff0c;赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻