日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

一篇學會 Rust 內存布局

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

 

本文是對 Rust內存布局[1] 的學習與記錄

 
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::<[i64; 4]>()
    );

    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 = (1, 2.0, "three");

這里元組包含一個i32,一個f64和一個字符串。編譯器會預先知道:

  • 元組元素類型為i32, f64, &str
  • i32占用4字節,f64占用8字節,&str占據一個指針的空間
  • 所以該元組占用的內存大小為4 + 8 + 8 = 20字節

這20字節的內存在編譯時就已分配,運行期不會改變。

如果后續試圖給這個元組添加或減少元素,編譯都會報錯。

所以說,元組的大小和內容是固定的,這是Rust實現方式的一部分。


更多可參考Rust 數據內存布局[2]

參考資料

[1]

Rust內存布局: https://www.bilibili.com/video/BV1Bm4y1c71r

[2]

Rust 數據內存布局: https://blog.csdn.NET/techdashen/article/details/120257323

分享到:
標簽:Rust
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定