如何用Allocator正确对齐分配可变大小的VarSized对象?
如何用Allocator为可变大小结构体分配内存并保证对齐?
首先定义可变大小的结构体:
struct VarSized { std::array<int, 500> fixedHeader; std::byte extraMemory[]; // 可变大小部分 };
需要实现如下模板方法,用于分配一个VarSized对象,其中extraMemory的大小为传入的numExtraBytes:
// 分配一个`VarSized`对象,其中`extraMemory`的大小为`numExtraBytes`。 template<typename Allocator> VarSized* allocateVarSized(size_t numExtraBytes, Allocator alloc = Allocator()) { // ... ? }
尝试过的两种方案及问题
方案1:绑定Allocator到VarSized,存在内存浪费
将Allocator重新绑定到VarSized类型,但无法直接指定额外字节数——因为Allocator分配该类型时,只能按sizeof(VarSized)的整数倍分配内存。以本例为例,VarSized的大小为2000字节,若仅请求1个额外字节,就需要分配4000字节而非2001字节,造成大量内存浪费。
对应的代码实现:
// 方案1:无法正确指定额外字节数 template<typename Allocator> VarSized* allocateVarSized1(size_t numExtraBytes, Allocator alloc = Allocator()) { using A = std::allocator_traits<Allocator>::template rebind_alloc<VarSized>; A a(alloc); return a.allocate(/* 无法在此处传入numExtraBytes :( */); }
方案2:绑定Allocator到std::byte,存在对齐风险
如果将Allocator重新绑定到std::byte类型,分配的内存无法保证满足int的对齐要求——因为alignof(std::byte)为1。若使用的Allocator不保证至少4字节的对齐,代码会触发未定义行为,因此该方案不可行。
对应的代码实现:
// 方案2:可能存在对齐错误 template<typename Allocator> VarSized* allocateVarSized2(size_t numExtraBytes, Allocator alloc = Allocator()) { using A = std::allocator_traits<Allocator>::template rebind_alloc<std::byte>; A a(alloc); /* 可能存在对齐错误 :( */ return reinterpret_cast<VarSized*>(a.allocate(sizeof(VarSized) + numExtraBytes)); }
当前困境与疑问
目前我能想到的最优方案是基于方案1,将额外字节数向上取整为sizeof(VarSized)的整数倍,但这在本例中会导致大量内存浪费。
难道没有办法用Allocator正确对齐地分配可变大小的对象吗?我需要一种能显式指定分配大小和对齐方式的方法,但Allocator似乎不提供该功能。
内容的提问来源于stack exchange,提问作者gexicide
相关产品推荐
相关产品推荐

