Rust編程知識拾遺:內存佈局

1、每種類型都有一個數據對齊屬性。在X86平臺上u64和f64都是按照32位對齊的。

2、一種類型的大小是它對齊屬性的整數倍,這保證了這種類型的值在數組中的偏移量都是其類型尺寸的整數倍,可以按照偏移量進行索引。需要注意的是,動態尺寸類型的大小和對齊可能無法靜態獲取。

3、結構體的對齊屬性等於它所有成員的對齊屬性中最大的那個。Rust會在必要的位置填充空白數據,以保證每一個成員都正確地對齊,同時整個類型的尺寸是對齊屬性的整數倍。

例子:

<code>struct  A { 
a: u8,
b: u32,
c:u16,
}/<code>

會填充為:

<code>struct  A { 
a: u8,
_pad1: [u8; 3], // 為了對齊b
b: u32,
c: u16,
_pad2: [u8; 2], // 保證整體類型尺寸是4的倍數
}/<code>

4、注意點,兩個同樣類型的複合類型其分佈規則並不一定一塵不變。例子:

<code>struct  A { 
a: i32,
b: u64,

}
struct B {
a: i32,
b: u64,
}/<code>

Rust中不保證A的實例和B的實例有同樣的數據填充和成員順序。

原因:Rust編譯器會進行優化。如下:

<code>struct  Foo { 
count: u16,
data1: T,
data2: U,
}
/<code>

對於上面的泛型結構體,Foo和Foo按照內存優化的原則要求兩者順序不一樣。

5、求解結構體的大小使用std::mem,有兩種方法,分佈是size_of_val和size_of,例子如下:

<code>use std::mem;
struct A {
a: u8,
b: u16,
}

fn main() {
let aa = A {a: 1, b:2};
println!("size = {}", mem::size_of_val(&aa));
println!("size = {}", mem::size_of::/<code>


分享到:


相關文章: