MST

星途 面试题库

面试题:Rust内存布局控制基础

在Rust中,如何使用`repr`属性来控制结构体的内存布局?请举例说明不同`repr`选项(如`repr(C)`、`repr(u8)`等)对结构体内存布局的影响。
20.2万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. repr(C)
    • 作用repr(C)使Rust结构体具有与C语言兼容的内存布局。这意味着字段按照它们在结构体定义中出现的顺序存储,并且使用C语言的对齐规则。
    • 示例
#[repr(C)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p = Point { x: 1, y: 2 };
    // 可以安全地将这个结构体传递给C函数(假设存在对应的C函数接口)
}
  1. repr(u8)
    • 作用repr(u8)将结构体表示为一个紧密排列的u8数组。结构体的所有字段被连续存储,没有任何填充,并且每个字段按照它们在结构体定义中的顺序占用尽可能少的字节。
    • 示例
#[repr(u8)]
struct SmallStruct {
    a: u8,
    b: u8,
}

fn main() {
    let s = SmallStruct { a: 10, b: 20 };
    // SmallStruct占用2个字节,因为它的字段紧密排列
}
  1. repr(packed)
    • 作用repr(packed)类似于repr(u8),它强制结构体使用最小的对齐方式,减少填充。但是与repr(u8)不同,它可以用于非字节大小的类型。
    • 示例
#[repr(packed)]
struct PackedPoint {
    x: i32,
    y: i32,
}

fn main() {
    let pp = PackedPoint { x: 1, y: 2 };
    // PackedPoint占用8个字节(假设i32是4字节),没有填充
}
  1. repr(Rust)
    • 作用repr(Rust)是Rust结构体的默认布局方式。Rust编译器会根据平台和优化策略来安排字段顺序和填充,以提高性能。通常,它会尝试将相似类型的字段分组,并使用合适的对齐方式。
    • 示例
struct DefaultPoint {
    x: i32,
    y: i32,
}

fn main() {
    let dp = DefaultPoint { x: 1, y: 2 };
    // DefaultPoint的布局由Rust编译器根据平台和优化策略决定
}

不同的repr选项会根据需求影响结构体的内存布局,repr(C)用于与C语言交互,repr(u8)repr(packed)用于紧凑存储,repr(Rust)是Rust默认的高性能布局方式。