Variant Vector容器TypeMemoryRequirement结构体内存对齐逻辑咨询
TypeMemoryRequirement模板类核心逻辑解析
首先给出完整代码(注:原代码中aling_of为拼写错误,正确应为align_of):
template <typename T> struct TypeMemoryRequirement { static constexpr size_t size_of = sizeof(T); static constexpr size_t aling_of = alignof(T); // extra space for align the pointer static constexpr size_t value = size_of + aling_of - 1; static constexpr size_t array_of(size_t count) { // only the first element gets aligned all follow up are tightly packed return 0 == count ? 0 : (value + ((count - 1) * size_of)); } static void *align_pointer(void *ptr) { auto asInt = reinterpret_cast<uintptr_t>(ptr); asInt = (asInt + aling_of - 1) & ~(aling_of - 1); return reinterpret_cast<void *>(asInt); } static const void *align_pointer(const void *ptr) { auto asInt = reinterpret_cast<uintptr_t>(ptr); asInt = (asInt + aling_of - 1) & ~(aling_of - 1); return reinterpret_cast<const void *>(asInt); } };
一、value的计算逻辑与作用
计算逻辑
value = sizeof(T) + alignof(T) - 1是内存对齐场景中经典的最坏空间预留计算式:它计算的是,从任意未对齐的起始地址开始,为了放下一个对齐后的T实例,需要预留的最大内存空间。
核心作用
当你拿到一块未对齐的原始内存时,调用align_pointer会将起始地址调整到最近的对齐地址,调整后的地址与原地址的偏移量最多为alignof(T)-1个字节。因此,预留sizeof(T) + alignof(T)-1字节的空间,就能保证无论原地址的对齐状态如何,调整后的地址都能完整放下一个T实例(对齐后的实例占sizeof(T)字节,加上最多alignof(T)-1字节的前置填充,总空间刚好被value覆盖)。
二、array_of方法的实现原理
代码逻辑拆解
array_of的设计完全服务于在未对齐内存块中构造对齐对象数组的场景,返回值分为两部分:
- 第一个元素的预留空间:使用
value,确保无论内存起始地址是否对齐,都能容纳第一个经过align_pointer调整后的T实例; - 后续元素的预留空间:从第二个元素开始,由于第一个元素已经是对齐状态,而C++标准规定
sizeof(T)必然是alignof(T)的整数倍,因此后续元素的起始地址会自动满足对齐要求,不需要额外填充,每个元素只需预留sizeof(T)字节即可。
场景验证
以T为int(sizeof=4,alignof=4)为例:
value = 4 + 4 -1 =7,表示最坏情况下需要7字节空间才能放下第一个对齐的int;array_of(3)=7 + 2*4=15:预留15字节空间,无论原始内存起始地址如何,都能放下3个连续对齐的int实例——即使原始地址偏移3字节才对齐,第一个int占4字节,后续两个int各占4字节,总占用12字节,15字节的预留空间完全覆盖。
内容的提问来源于stack exchange,提问作者SigmaKlim
相关产品推荐
相关产品推荐

