Rust 编程:内存布局

1、每种类型都有一个数据对齐属性。在X86平台上u64和f64都是按照32位对齐的。

2、一种类型的大小是它对齐属性的整数倍,这保证了这种类型的值在数组中的偏移量都是其类型尺寸的整数倍,可以按照偏移量进行索引。需要注意的是,动态尺寸类型的大小和对齐可能无法静态获取。

3、结构体的对齐属性等于它所有成员的对齐属性中最大的那个。Rust会在必要的位置填充空白数据,以保证每一个成员都正确地对齐,同时整个类型的尺寸是对齐属性的整数倍。

例子:

struct  A { 
    a: u8, 
    b: u32, 
    c:u16, 
}

会填充为:

struct  A { 
    a: u8, 
    _pad1: [u8; 3], // 为了对齐b 
    b: u32, 
    c: u16, 
    _pad2: [u8; 2], // 保证整体类型尺寸是4的倍数 
}

4、注意点,两个同样类型的复合类型其分布规则并不一定一尘不变。例子:

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

Rust中不保证A的实例和B的实例有同样的数据填充和成员顺序。

原因:Rust编译器会进行优化。如下:

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

对于上面的泛型结构体,Foo<u32, u16>和Foo<u16, u32>按照内存优化的原则要求两者顺序不一样。

5、求解结构体的大小
使用std::mem,有两种方法,分布是size_of_val和size_of,例子如下:

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::<A>());
    println!("Hello, world!");
}
本作品采用《CC 协议》,转载必须注明作者和本文链接

令狐一冲

讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!