Rust内存布局


alt

题图忘了来自哪里..


整型,浮点型,struct,vec!,enum


本文是对 Rust内存布局 的学习与记录


struct A {
    a: i64,
    b: u64,
}

struct B {
    a: i32,
    b: u64,
}

struct C {
    a: i64,
    b: u64,
    c: i32,
}

struct D {
    a: i32,
    b: u64,
    c: i32,
    d: u64,
}

fn main() {
    println!("i32类型占的内存空间为:{}字节", std::mem::size_of::<i32>());
    println!("i64类型占的内存空间为:{}字节", std::mem::size_of::<i64>());
    println!(
        "[i64;4]占的内存空间为:{}字节",
        std::mem::size_of::<[i644]>()
    );

    println!("结构体A占的内存空间为:{}字节", std::mem::size_of::<A>());
    println!("结构体B占的内存空间为:{}字节", std::mem::size_of::<B>());
    println!("结构体C占的内存空间为:{}字节", std::mem::size_of::<C>());
    println!("结构体D占的内存空间为:{}字节", std::mem::size_of::<D>());
}


输出

i32类型占的内存空间为:4字节
i64类型占的内存空间为:8字节
[i64;4]占的内存空间为:32字节
结构体A占的内存空间为:16字节
结构体B占的内存空间为:16字节
结构体C占的内存空间为:24字节
结构体D占的内存空间为:24字节

没啥好说的,和Go一样,struct会存在内存对齐/内存填充(8字节对齐)

D是因为编译器会优化内存布局,字段顺序重排



Rust中的Vec!和Go中的slice差不多,都是占24Byte,三个字段

struct SimpleVec<T> {
    len: usize,      // 8
    capacity: usize//8
    data: *mut T,    //8
}

fn main() {
    println!(
        "Vec!类型占的内存空间为:{}字节",
        std::mem::size_of::<SimpleVec<i32>>()
    );

    println!(
        "Option<i64>类型占的内存空间为:{}字节",
        std::mem::size_of::<Option<i64>>()
    );
}
Vec!类型占的内存空间为:24字节
Option<i64>类型占的内存空间为:16字节

但是对于enum类型,

会有一个tag字段,uint64,来标记变体,是None值还是Some值

struct Option {
    uint64 tag; // 占8字节 Some None
    i64//实际存放的数据
}

struct SimpleVec<T> {
    len: usize,      // 8
    capacity: usize//8
    data: *mut T,    //8
}

enum Data {
    // tag,uint64,8字节
    I32(i32),             //  4字节,但需内存对齐到8字节?
    F64(f64),             // 8字节
    Bytes(SimpleVec<u8>), // 24字节
}

fn main() {
    println!(
        "Data这个Enum类型占的内存空间为:{}字节",
        std::mem::size_of::<Data>()
    );
}

输出为:

Data这个Enum类型占的内存空间为:32字节


Rust的enum类似C++ std::variant的实现(大致是用union实现的)

union的内存大小是其成员中最大的那个成员的大小,

类似的,对于Data这个Enum类型,会选择最大的那个成员的大小

所以24+tag的8字节,最终为32字节 (tag在这里就用来标识其为i32,还是f64,或者是Vec )


嵌套的枚举:

struct SimpleVec<T> {
    len: usize,      // 8
    capacity: usize//8
    data: *mut T,    //8
}

enum Data {
    // tag,uint64,8字节
    I32(i32),             //  4字节,但需内存对齐到8字节?
    F64(f64),             // 8字节
    Bytes(SimpleVec<u8>), // 24字节
}

type OptData = Option<Data>;

fn main() {
    println!(
        "OptData这个Option类型占的内存空间为:{}字节",
        std::mem::size_of::<OptData>()
    );
}

输出:

OptData这个Option类型占的内存空间为:32字节

因为编译器会对嵌套的枚举类型进行优化,会将其tag展开, 把多个tag合在一起了,类似下面:

展开变成一个枚举(None是uint64,能标识非常多信息)

type OptData = Option<Data>;

enum Option {
    Some,
    None,
}

enum OptData_ {
    I32(i32);
    F64(f64);
    Bytes(SimpleVec<u8>),
    None
}


元组tuple


rust中的元组大小固定吗?

在Rust中,元组的大小是固定的。这里解释一下元组大小固定的含义:

  • 元组中的元素类型和数量在编译期就已经确定,不能在运行期修改。

  • 编译器会根据元组中元素的类型,预先分配足够的内存用于存储这些元素。

  • 元组的内存布局和大小也在编译期就确定下来了,运行期不会改变。

  • 尝试创建包含不同类型或数量元素的元组,是编译时错误。

举个例子:

let tuple = (12.0"three");

这里元组包含一个i32,一个f64和一个字符串。编译器会预先知道:

  • 元组元素类型为i32, f64, &str
  • i32占用4字节,f64占用8字节,&str占据一个指针的空间
  • 所以该元组占用的内存大小为4 + 8 + 8 = 20字节

这20字节的内存在编译时就已分配,运行期不会改变。

如果后续试图给这个元组添加或减少元素,编译都会报错。

所以说,元组的大小和内容是固定的,这是Rust实现方式的一部分。



更多可参考 Rust 数据内存布局

本文由 mdnice 多平台发布

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

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

相关文章

优思学院|如何在企业中实施降本增效策略,实现财务突破

在当今竞争激烈的商业环境中&#xff0c;企业降低成本并提高效益变得至关重要。本文将深入探讨如何降本增效&#xff0c;以及实施这些策略的方法。 提到降本增效或提升生产效率&#xff0c;第一个被提出来检讨的一定是直接部门。但是如果无视于日渐臃肿的间接部门&#xff0c;…

TS 函数及多态

TS 能推导出函数体中的类型&#xff0c;但多数情况下无法推导出参数的类型&#xff0c;只有少数特殊情况下能根据上下文推导参数的类型。返回类型能推导出&#xff0c;不过也可以显式注解。 1 声明和调用函数 一般来说&#xff0c;在方法中的this值为调用该方法时位于点号左侧…

大模型下交互式数据挖掘的探索与发现

在这个数据驱动的时代&#xff0c;数据挖掘已成为解锁信息宝库的关键。过去&#xff0c;我们依赖传统的拖拉拽方式来建模&#xff0c;这种方式在早期的数据探索中起到了作用&#xff0c;但随着数据量的激增和需求的多样化&#xff0c;它的局限性逐渐显露。 >>>> 首…

App备案与iOS云管理式证书 ,公钥及证书SHA-1指纹的获取方法

​ 引言 在iOS应用程序开发过程中&#xff0c;进行App备案并获取公钥及证书SHA-1指纹是至关重要的步骤。本文将介绍如何通过appuploader工具获取iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹&#xff0c;帮助开发者更好地理解和应用该过程。 正文 iOS应用程序…

【从删库到跑路 | MySQL总结篇】表的增删查改(进阶上)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】&#x1f388; 本专栏旨在分享学习MySQL的一点学习心得&#xff0c;欢迎大家在评论区讨论&#x1f48c; 目录 一、数据…

Node.js入门指南(五)

目录 MongoDB 介绍 下载与启动 命令行交互 Mongoose 代码模块化 图形化管理工具 hello&#xff0c;大家好&#xff01;上一篇文章我们介绍了express框架&#xff0c;这一篇文字主要介绍MongoDB。来对数据进行存储以及操作。 MongoDB 介绍 各位小伙伴应该多多少少都有接…

uniapp基础-教程之HBuilderX基础常识篇03

该内容为了大家更好的理解&#xff0c;将每个页面进行分离&#xff0c;单独创建项目&#xff0c;如在index中之写只写了一个搜索框&#xff0c;将其他页面分别放在HBuilderX目录中的components中&#xff0c;没有的可自行创建。 然后在components中创建轮播图新建一个swiper.v…

正则化与正则剪枝

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 引言正则化为什么会过拟合拉格朗日与正则化梯度衰减与正则化 应用解决过拟合网络剪枝 …

Linux篇:文件管理

一、共识原理&#xff1a; 1. 文件内容属性&#xff0c;内容与属性都是数据&#xff0c;都要在磁盘中保存。 2. 文件分为打开的文件和没打开的文件。 3. 研究打开的文件&#xff1a;本质是研究进程和文件的关系&#xff0c;因为是进程负责打开文件。 4. 没打开的文件在存储介质…

红黑树(万字图文详解)

红黑树 1. 红黑树的概念2. 红黑树的性质3. 红黑树节点的定义4. 红黑树结构5. 红黑树的插入操作5.1 按照二叉搜索的树规则插入新节点5.2 检测新节点插入后&#xff0c;红黑树的性质是否造到破坏5.2.1 情况一: cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u存在且为红…

智能优化算法应用:基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蜻蜓算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蜻蜓算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

【springboot】宝塔简单部署springboot 配置https

宝塔简单部署springboot配置https 需求步骤1. springboot通过maven组件打成jar包2. 将jar包部署到宝塔上3. 下载安装nginx并创建网站节点4. 设置域名或者IP5. 设置反向代理:代理后端服务的ip和端口7. 配置SSL/TLS 需求 宝塔部署springboot项目,用nginx反向代理后端IP端口&…

深度学习黎明时期的LeNet:揭开卷积神经网络的序幕

在深度学习的历史长河中&#xff0c;Yann LeCun 的 LeNet 是一个里程碑式的研究成果&#xff0c;它为后来的卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;CNN&#xff09;的发展奠定了基础。LeNet 的诞生标志着深度学习黎明时期的到来&#xff0c;为人工…

【已解决】在windows下,gitlab修改了密码导致remote: HTTP Basic: Access denied

背景 网上好多答案遇到此问题都是修改凭证,故写此文。 在控制面板》用户账户》凭据管理器》管理windows凭据》普通凭据 --找到对应的git地址&#xff0c;编辑用户名和密码 本文解决方案适用于windows下没有凭证的情况&#xff0c;因修改密码导致下拉代码出错的情况。 Git是常…

Scrapy框架内置管道之图片视频和文件(一篇文章齐全)

1、Scrapy框架初识&#xff08;点击前往查阅&#xff09; 2、Scrapy框架持久化存储&#xff08;点击前往查阅&#xff09; 3、Scrapy框架内置管道 4、Scrapy框架中间件&#xff08;点击前往查阅&#xff09; Scrapy 是一个开源的、基于Python的爬虫框架&#xff0c;它提供了…

JAVA配置jdk17 Graa1VM

按照网上内容下载好对应的jdk17版本的Graa1VM&#xff0c; 解压后&#xff0c;修改环境变量中的JAVA_HOME为当前的目录&#xff0c;例如 D:\ruanjian\jdk\gra_jdk17\graalvm-ce-java17-22.3.0 。 然后在命令行中输入java -version的时候&#xff0c; 返回的并不是 Graa1VM 相关…

文件权限中 chmod、u+x、u、r、w、x分别代表什么

Linux系统中的每个文件和目录都有访问许可权限&#xff0c;如下面所示&#xff1a; 要说清楚问题&#xff0c;我们截取一些内容&#xff1a; ypyubuntu:~$ ls -l drwxr-xr-- 2 ypy ypy 4096 Nov 30 18:33 Desktop/ drwxr-xr-- 2 ypy ypy 4096 Nov 30 18:33 Documen…

【扩散模型】DDIM从原理到实战

DDIM从原理到实战 1. DDIM简介2. 实战DDIM2.1 载入一个预训练过的pipeline2.2 DDIM采样2.3 反转&#xff08;invert&#xff09; 3. 组合封装参考资料 DDPM过程的一个问题是在训练后生成图像的速度。当然&#xff0c;我们可能能够生成令人惊叹的图像&#xff0c;但生成一张图像…

本地训练,立等可取,30秒音频素材复刻霉霉讲中文音色基于Bert-VITS2V2.0.2

之前我们使用Bert-VITS2V2.0.2版本对现有的原神数据集进行了本地训练&#xff0c;但如果克隆对象脱离了原神角色&#xff0c;我们就需要自己构建数据集了&#xff0c;事实上&#xff0c;深度学习模型的性能和泛化能力都依托于所使用的数据集的质量和多样性&#xff0c;本次我们…

【密码学引论】序列密码

第五章 序列密码 1、序列密码 定义&#xff1a; 加密过程&#xff1a;把明文与密钥序列进行异或运算得到密文解密过程&#xff1a;把密文与密钥序列进行异或运算得到明文以字/字节为单位加解密密钥&#xff1a;采用一个比特流发生器随机产生二进制比特流 2、序列密码和分组密…