Rust中级教程:指针生态(引用、原始指针、智能指针)and内存操作(Stack、Heap)

news2025/2/27 17:31:57

指针的一些概览知识点

1.内存地址:指代内存中单个字节的一个整数。

指针(原始指针):就是指向某种类型的一个内存地址。
引用:就是指针,是rust提供的一种抽象,如果是动态大小,就是一个指针和一个具有额外保证的一个整数。

2.引用的大小和指针一样,它的大小用usize来表示,和系统的位数有关,在32位cpu上是4字节,在64位cpu上是8字节。
static B:[u8;2]=[11,22];
let b:Box<[u8]>=Box::new(B);
//这里的B的所有权跟着Box转移到b里面了。指针的大小比引用大一倍,Box会获取所有权,复制操作?
//指向的地址发生变化,static是在静态内存里面,而Box放在堆内存上了。
let c:&[u8;2]=&B;
//这样写就是普通的引用,指向的地址就是B的地址。

在这里插入图片描述

3.Cow:copy on write,在需要写的时候才会复制,否者只读不复制,

原始指针的操作需要在unsafe里面,下面就是原始指针,*mut T 和 const T,原始指针没有Rust标准保障的内存地址。
比如
mut String就是指向String类型的原始指针是可变的。原始指针就是操作方便,效率高。

//这个代码的作用是将一个数组里的数字解码成字符串。
let a:i64=42;
let b:String;
let c:Cow<str>;

let a_ptr:*const i64=&a as *const i64;
let b_ptr:*mut u8=&B as *const u8 as *mut u8;//原始指针,先变成不可变的,再变成可变的。
b=String::from_raw_parts(buf:b_ptr,length:10,capacity:10);

let c_ptr:*const i8=&C as *const u8 as *const c_char;
c=CStr::from_ptr(c_ptr).to_string_lossy();
4.解引用:dereference,指针生态

因为在底层上,引用被实现为原始指针,但引用带有额外的保证,所以尽量使用引用而不是原始指针。
访问原始指针的值总是unsafe的,并且是不拥有所有权的,允许多个原始指针指向统一数据。
什么时候使用原始指针?
不可避免的时候:和C交互。和共享对某些内容的访问至关重要,运行时性能要求高。
在这里插入图片描述
在这里插入图片描述

内存简介

1.值,变量:存储值的地方,存在于stack上面,槽。

变量的高级模型:当变量被访问的时候,可以从变量的上次访问到这次访问画一条线,从而在两次访问之间建立了依赖关系。
如果变量没有被初始化,或者变量被移动了,就不能从它那画线了。
使用这种模型,程序会出现很多的依赖关系,依赖线,叫做flow。
每个flow都在追踪一个值的特定实例的生命周期,当有分支存在的时候,flow可能分叉或合并,每个分成都在追逐该值的不同生命周期。
在程序中的任何给定点,编译器可以检查所有的flow是否相互兼容、并行存在。
例如:一个值不可能有两个具体可变访问的并行flow;也不能一个flow借用了一个值,但却没有flow拥有改值。

2.变量的低级模型

多次赋值会被覆盖。

3. 内存区域

三个比较重要的区域:stack、heap、static内存。
想要把数据放在Stack,编译器必须知道类型的大小。
1.Stack Frame(栈帧):每个函数被调用,在stack的顶部会分配一个连续的内存块,叫做stack frame,每个frame的大小是不一样的。
接近Stack底部附近的是main函数的栈帧,随着函数的调用,其余的frame都被推到栈上。
函数的frame包含函数的所有变量,以及函数所带的参数。当函数返回时,它的frame就会被回收。但是构成函数本地变量值的那些字节不会被立即擦除,访问不安全,后续有可能会被重写。
在函数调用期间,Stack Frame会包含函数的状态,当一个函数在另外一个内调用时,原来的函数的值会被及时冻结。
Stack Frame为函数参数,指向原来调用栈的指针以及本地变量(不包括在heap上分配的数据)提供空间。
为什么stack快呢?因为函数的所有变量在内存里都是紧紧挨着的。
例子:满足传递&str类型和String类型同时传递,一个在stack上,一个在heap上。

fn main(){
let pw:&str="juskl";
let is_strong:bool=is_strong(pw);
}
fn is_strong<T:Into<String>>(password:T)->bool{
password.into().len()>5}

任何在Stack上的frame里存储的变量,在frame消失之后,他就无法访问了。所以任何到这些变量引用的生命周期,最多只能和frame一样长。
2.Stack Pointer(栈指针):随着程序的进行,CPU里有一个游标会随着更新,他反应的是当前stack frame的当前地址。随着函数的不断调用,stack增长或者减少。

3.heap内存
heap意味着混乱。是一个内存池,并没有绑定到当前程序的调用栈,是为在编译时没有已知大小的类型准备的。
什么叫在编译时大小不已知呢?一些类型随着时间会变大变小,例如String,Vec。另一些类型的大小不会改变,但无法告诉编译器需要分配多少内存,这些都叫做动态大小的类型。还有就是trait对象,通过模拟动态语言,允许将多个类型放进一个容器。
heap允许你显式的分配连续的内存块,当这么做的时候,你会得到一个指针,它指向内存块开始的地方。里面的值会一直有效,直到你显式的对它释放。如果你想让值活得比当前函数frame的生命周期长,就很有用。
这种值活得长的方法在stack里面也可以使用,如果值是函数的返回值,那么调用函数可以在它的stack上留一些空间给被调用的函数让它把值在返回前写入进去。

4.heap线程安全的例子
如果想把值送到另一个线程,当前线程可能根本无法与那个线程共享stack frame,你就可以把它放在heap上。
因为函数返回时heap上的分配并不会消失,所以你在一个地方为值分配内存,把指向它的指针传递给另一个线程,就可以让那个线程继续安全的操作这个值。
换一种说法:当你分配heap内存时,结果指针会有一个无约束的生命周期,你的程序让他话多久都行。

5.heap交互机制
heap上的变量,都必须通过指针来访问。想要进行同类型操作,需要解引用。
Rust里与Heap交互的首要机制就是Box类型。当Box::new(value)时,值就会放在heap上,返回的(Box)就是指向heap上的值的指针。当Box被丢弃的时候,内存就会被释放。
如果忘记释放内存,就会导致内存泄漏。drop(a),在生命周期结束之前进行释放,这里的a是放在stack上的,释放之后堆上的数据不会立刻释放,只是标记为可以使用覆盖。

6.static静态内存
static是指的是程序编译之后的文件中几个密切相关的区域。static内存里的值会在你的程序的整个执行过程一直存活,通常是只读的。
‘static生命周期,例如T:’static表示类型T可以存活我们想要的任意时长,直到程序结束。同时要求T是拥有所有权的和自给自足的,意思就是它不借用其他(非static)值,或者它借用的东西也都是static的。
const和static的区别:const只是一个名字,没有任何内存或者存储,在编译期间被替换为某个特定的值。

内存第二部分

1.动态内存分配

当程序需要更多的内存时,就需要从OS请求。dynamic allocation
首先,通过系统调用从OS请求内存,alloc()。
然后使用分配的内存,
最后释放不再需要的内存给OS,free()。

2.为什么Stack和Heap存在性能上的差异?

Stack和heap只是概念而已,内存在物理上没有这两个区域。
访问stack快:函数本地变量在RAM上彼此相邻(连续布局),连续布局对缓存友好。
访问heap慢,分配在heap上的变量不太可能彼此相邻。访问heap上的数据涉及对指针进行解引用(页表查找和去访问主存)
stack上的数据结构在生命周期内大小不能变,heap上的数据结构更加灵活,因为指针可以改变。

3.虚拟内存

程序的内存视图,程序可访问的所有数据都是由操作系统在其地址空间提供。
segmentaation fault:当cpu或os检测到程序试图请求非法(禁止访问)的内存地址时所产生的错误。
segment:虚拟内存中的块,虚拟内存被划分为块,以最小化虚拟和物理地址之间转换所需的空间。
访问越界的内存,OS就会关掉你的程序。
程序里所用的地址都是虚拟地址,虚拟地址都会被转化为物理地址。

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

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

相关文章

标记肽MGP-7-氨基-4-甲基香豆素、1926163-53-2、Met-Gly-Pro-AMC

蛋氨酸氨基肽酶1D和2的荧光底物。编号: 152397 中文名称: 标记肽MGP-7-氨基-4-甲基香豆素 英文名: H-Met-Gly-Pro-AMC CAS号: 1926163-53-2 单字母: H2N-MGP-AMC 三字母: H2N-Met-Gly-Pro-AMC 氨基酸个数: 3 分子式: C22H28N4O5S1 平均分子量: 460.55 精确分子量: 460.18 等电点…

【SVN】SVN服务端地址变动,idea切换SVN地址

公司切换了SVN服务端的制度&#xff0c;需要本地对应切换SVN地址&#xff0c;以下为具体步骤 错误方式 直接 项目上右键 --> Subversion --> Relocate &#xff0c;修改 To URL 的值&#xff0c;会报错 https://XXXXX is not the root of the repository 的错误 正确的…

Communication-Efficient Learning of Deep Networks from Decentralized Data

international conference on artificial intelligence and statistics Summary 当前机器学习模型训练中存在着数据隐私保护问题&#xff0c;所以作者提出了FL概念。通过分布式隐私保护进行训练模型。对不平衡、non-IID的数据也更合适。 主要提出了FedSGD和FedAvg算法。FedAv…

Andriod开发R文件爆红相关解决方法及排查方案

1.首先尝试下基本的处理方法&#xff1a; 在IDE中工具栏处选择build 尝试clean project&#xff0c;然后再进行rebuild project或者是make project 若使用的是IDEA或Android studio&#xff0c;在上述方法尝试后可以尝试工具栏中File->Setting->Invalidate Caches/Rest…

微信小程序(基础语法)

文章目录基本组件视图容器viewscroll-viewswiper和swiper-item基础内容组件textrich-text其他常用组件buttonimagenavigator基本模板数据绑定插值表达式事件绑定常用事件在事件处理函数中为data的数据赋值事件传参bindinput的使用小程序中的v-model条件渲染wx:ifhidden列表渲染…

一些关于通信拓扑、图论的内容笔记

链接&#xff1a;https://zhuanlan.zhihu.com/p/373368383 目前主要是这一个系列&#xff0c;记下来怕我过后忘了。 别处看到的&#xff08;大概率3B1B&#xff09;----走桥的问题----d偶数 多智能体一致性问题&#xff08;分蛋糕&#xff09; 入度 出度 &#xff1a;信息流…

007_补充_ Pytorch 反向传播和Neural ODE的反向传播

一、Pytorch反向传播 首先是第一个小例子&#xff0c;训练模型拟合 y true_w * x true_b&#xff0c;模型的参数为 param_w, param_b import torchtrue_w torch.Tensor([[2.0, 3.0], [4.0, 5.0]]) # 初始化真实的参数 true_b torch.Tensor([[1.0, 2.0], [3.0, 4.0]]) #…

linux安装jdk17

登录linux 我使用的是Alibaba Cloud Linux 3.2104 LTS 64位操作系统&#xff0c;登录后结果如下&#xff1a; Welcome to Alibaba Cloud Elastic Compute Service !Updates Information Summary: available7 Security notice(s)5 Important Security notice(s)2 Moderate Sec…

2023最新SSM计算机毕业设计选题大全(附源码+LW)之java校园二手商品交易系统p11v7

毕业设计说实话没有想象当中的那么难&#xff0c;导师也不会说刻意就让你毕设不通过&#xff0c;不让你毕业啥的&#xff0c;你只要不是太过于离谱的&#xff0c;都能通过的。首先你得要对你在大学期间所学到的哪方面比较熟悉&#xff0c;语言比如JAVA、PHP等这些&#xff0c;数…

laravel对于数据量特别大的导出excel的提速方案

背景&#xff1a;一些业务场景需要导出excel的需求&#xff0c;但是面对日益增长的数据&#xff0c;要导出的数据会越来越大。生成表格的时间也会越来越慢。针对这个问题&#xff0c;目前的业务通过两个角度去提速。 1&#xff1a;异步导出 如果数据量达到一定的体量&#xf…

【毕业设计】大数据大众点评评论文本分析 - python 数据挖掘

文章目录0 前言1 爬虫1.1 整体思路1.2 网页爬取和解析1.3 数据存储1.4 反爬虫对抗2 探索性分析与文本数据预处理2.1 探索性分析2.2 数据预处理2.3 词云展示3 文本的情感分析3.1 先上结果3.2 文本特征提取&#xff08;TF-IDF&#xff09;3.3 机器学习建模3.4 最后输出的准确率4 …

java ssh校园拼餐系统

首先在系统前台&#xff0c;游客用户可以经过账号注册&#xff0c;管理员审核通过后&#xff0c;用账号密码登录系统前台&#xff0c;查看拼餐服务、网站公告、文明拼餐员、会员风彩、系统简介、咨询信息、拼餐信息等栏目信息&#xff0c;进行在线咨询和管理员交流&#xff0c;…

LTSPICE使用教程:二极管钳位电路仿真

在我们查看芯片内部的设计电路时&#xff0c;通常会发现以下的电路结构&#xff1a; 当定义pin脚输入电压Vpin&#xff0c; 1.Vpin>VDD,二极管D1导通&#xff0c;D2截止&#xff0c;此时无论怎样继续加大VPIN的输入电压时&#xff0c; 进入到管脚内部的电压会被钳制在Vint…

【RocketMQ中生产者生产消息的高可用机制、消费者消费消息的高可用机制、消息的重试机制、死信队列于死信消息】

一.知识回顾 【0.RocketMQ专栏的内容在这里哟&#xff0c;帮你整理好了&#xff0c;更多内容持续更新中】 【1.Docker安装部署RocketMQ消息中间件详细教程】 【2.RocketMQ生产者发送消息的三种方式:发送同步消息、异步消息、单向消息&案例实战&详细学习流程】 【3.Rock…

野火FPGA入门(5)

文章目录第17讲&#xff1a;触摸按键控制LED灯第18讲&#xff1a;流水灯第19讲&#xff1a;呼吸灯第20讲&#xff1a;状态机第21讲&#xff1a;无源蜂鸣器驱动实验第17讲&#xff1a;触摸按键控制LED灯 触摸按键可分为四大类&#xff1a;电阻式、电容式、红外感应式、表面声波…

调优工具常用命令

语法格式 mysqldumpslow [ OPTS... ] [ LOGS... ] //命令行格式常用到的格式组合 -s 表示按照何种方式排序c 访问次数l 锁定时间r 返回记录t 查询时间al 平均锁定时间ar 平均返回记录数at 平均查询时间 -t 返回前面多少条数据 -g 后边搭配一个正则匹配模式&#xff0c;大小写…

机械专业学子的芯片封装仿真“逆袭之路”

作者&#xff1a;萧显军 导读&#xff1a;近期&#xff0c;ANSYS公司给清华大学集成电路学院捐赠了一批业界领先的计算机辅助工程(CAE)软件及自动化(EDA)软件&#xff0c;为清华大学的芯片设计仿真的教学科研工作提供更强大的软件服务与技术支撑。 捐的仿真软件包括ANSYS涉及…

小白学Java

ip地址&#xff1a;用于唯一识别标记网络中的每一台计算机 查看方法&#xff1a;ipconfig ip地址的表示形式&#xff1a;点分十进制 xx.xx.xx.xx 每个十进制数的范围&#xff1a;0-255 ip地址的组成 网络地址主机地址 ipv4地址分类&#xff1a; &#xff08;特殊&#xff1a;…

一、react简介

目标 理解react这个框架在前端开发中的地位理解react诞生的原因和意义&#xff08;react是一个用于快速构建前端视图的javaScript库&#xff09;理解什么是虚拟dom、原生js模拟出虚拟dom的表示&#xff0c;模拟出创建虚拟dom的方法&#xff0c;模拟出虚拟dom转换成真实dom的方…

什么是甘特图?什么是项目管理?

数字化与信息化早已成为现今人们工作和生活中不可缺少的一部分。尤其是随着科学技术的进步&#xff0c;人们对数字化的期待也越来也高。作为项目管理中常备的工具&#xff0c;甘特图已经成为不少业内人士中常备的“神器”了。然而依旧有人搞不清甘特图与项目管理区别究竟在哪里…