如何以方便的方式对齐堆(在盒子中)上的内存?

phi*_*611 2 heap-memory alignment rust

我想将堆内存对齐到特定的对齐边界。该边界在编译时已知。无论如何,Box抽象不允许我指定某种对齐方式。编写我自己的Box抽象也感觉不对,因为所有 Rust 生态系统都Box已经使用了。实现堆分配对齐的便捷方法是什么?

PS:在我的具体情况下,我需要页面对齐。

Aid*_*en4 6

如果 nightly 可以接受,AllocatorAPI 提供了一种相当方便的方法来执行此操作:

#![feature(allocator_api)]

use std::alloc::*;
use std::ptr::NonNull;
struct AlignedAlloc<const N: usize>;


unsafe impl<const N: usize> Allocator for AlignedAlloc<N> {
    fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
        Global.allocate(layout.align_to(N).unwrap())
    }
    unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
        Global.deallocate(ptr, layout.align_to(N).unwrap())
    }
}

fn main() {
    let val = Box::new_in(3, AlignedAlloc::<4096>);
    let ptr: *const u8 = &*val;
    println!(
        "val:{}, alignment:{}",
        val,
        1 << (ptr as usize).trailing_zeros()
    );
}
Run Code Online (Sandbox Code Playgroud)

操场

如果您愿意,还可以添加对使用其他分配器或动态选择值的支持。

编辑:想一想,这种方法也可以通过GlobalAlloc特征和#[global_allocator]属性在稳定中使用,但是设置一个分配器以这种方式强制所有分配对齐到相同的对齐方式,所以如果您需要确保相对较小的对齐方式,但对于页边界对齐来说可能不是一个好主意。

编辑2:从使用System分配器切换到Global分配器,因为它与该allocater_api功能捆绑在一起,并且它是更明智和可预测的默认值。