内存对齐是编译器为适配CPU批量读取硬件特性而强制变量地址满足特定倍数约束的机制,按类型自然对齐(alignof返回最小对齐值),可用alignas显式指定更大对齐,结构体通过填充满足成员及自身对齐要求,并影响缓存行、DMA、SIMD和ABI。

内存对齐是编译器为提升CPU访问效率,强制让变量的起始地址满足特定倍数约束的机制。它不是C++标准“发明”的规则,而是对硬件特性的适配——现代CPU通常按字(如4字节、8字节)批量读取内存,若一个int(4字节)跨两个缓存行存放,一次读取就可能触发两次内存访问甚至总线锁,性能骤降。因此,编译器默认按类型自然对齐(natural alignment),即对齐值等于其sizeof(基本类型)或最大成员对齐值(结构体)。
alignof:获取类型的对齐要求
alignof(T) 是编译期常量表达式,返回类型T所需的最小字节对齐值(以size_t形式)。它不关心对象是否存在,只看类型定义本身。
- int a; → alignof(int) 通常是4(x86-64下常见,但标准只要求≥2)
- double b; → alignof(double) 通常是8(因多数平台双精度需8字节对齐)
- struct S { char c; double d; }; → alignof(S) 是8,因为d要求8字节对齐,整个结构体必须满足最严格成员的对齐
alignas:显式指定对齐方式
alignas(N) 是声明说明符,用于强制增大变量或类型的对齐要求(N必须是2的幂,且不能小于该类型的自然对齐值)。
- alignas(16) int x; → x的地址一定是16的倍数(即使int本身只需4字节对齐)
- alignas(32) struct CacheLineData { ... }; → 整个结构体按32字节对齐,适合手动控制缓存行布局
- alignas(std::max_align_t) char buf[1024]; → 确保buf可安全用于placement new构造任意标准类型
注意:alignas(1) 合法但无实际效果(所有类型天然满足1字节对齐);alignas(3) 非法(非2的幂);alignas(2) double d; 会编译失败(违反double自然对齐要求)。
立即学习“C++免费学习笔记(深入)”;
结构体内存布局与填充(padding)
结构体总大小和成员偏移由对齐规则共同决定:每个成员按自身对齐值对齐,编译器在前一成员后插入必要填充字节,使下一成员地址满足其对齐要求;结构体总大小还需向上补齐到自身对齐值的整数倍。
-
struct A { char a; int b; };
→ a在offset 0,b需4字节对齐,故插入3字节padding(offset 1–3),b在offset 4;结构体大小=8(4+4),而非5 -
struct B { alignas(8) char a; int b; };
→ a被强制8字节对齐,所以a在offset 0或8;若a在0,则b仍需4字节对齐(offset 8即可),但结构体alignof(B)=8,最终大小至少为16(取决于a是否占位)
底层影响:cache line、DMA、SIMD与ABI
对齐不只是“不崩溃”,更直接影响硬件行为:










