我试图通过使用像 C 的灵活数组成员这样的东西来避免多个堆分配。为此,我需要分配一个未定义大小的结构,但我没有找到任何通过智能指针来实现的方法。我对 尤其感兴趣Rc,但这也是 的情况Box,所以这就是我将在示例中使用的内容。
这是我迄今为止最接近的:
use std::alloc::{self, Layout};
struct Inner {/* Sized fields */}
#[repr(C)] // Ensure the array is always last
// Both `inner` and `arr` need to be allocated, but preferably not separately
struct Unsized {
inner: Inner,
arr: [usize],
}
pub struct Exposed(Box<Unsized>);
impl Exposed {
pub fn new(capacity: usize) -> Self {
// Create a layout of an `Inner` followed by the array
let (layout, arr_base) = Layout::array::<usize>(capacity)
.and_then(|arr_layout| Layout::new::<Inner>().extend(arr_layout))
.unwrap(); …Run Code Online (Sandbox Code Playgroud) 我需要分配一个缓冲区来读取 a File,但是这个缓冲区必须与缓存行的大小(64 字节)对齐。我正在寻找一个有点像这样的功能Vec:
pub fn with_capacity_and_aligned(capacity: usize, alignment: u8) -> Vec<T>
Run Code Online (Sandbox Code Playgroud)
这将为我提供所需的 64 字节对齐。这显然不存在,但可能有一些我不知道的等价物(即“黑客”)。
所以,当我使用这个函数(它会给我所需的对齐)时,我可以安全地编写这段代码:
#[repr(C)]
struct Header {
magic: u32,
some_data1: u32,
some_data2: u64,
}
let cache_line_size = 64; // bytes
let buffer: Vec<u8> = Vec::<u8>::with_capacity_and_alignment(some_size, cache_line_size);
match file.read_to_end(&mut buffer) {
Ok(_) => {
let header: Header = {
// and since the buffer is aligned to 64 bytes, I wont get any SEGFAULT
unsafe { transmute(buffer[0..(size_of::<Header>())]) }
};
}
}
Run Code Online (Sandbox Code Playgroud)
并且不会因为对齐问题(例如启动指令)而出现任何恐慌。