为何仅含数组类型的结构体内存对齐值始终为1?(MSVC x64)
内存对齐与结构体数组的对齐疑惑
在探索内存对齐(memory alignment)与填充(padding)时,原本以为已掌握相关知识,直到遇到以下情况:
struct Example { int x1; // 4 char c; // 1 + 3 padding int x2; // 4 }; static_assert(sizeof Example == 12, "Incorrect size"); // OK struct Example2 { long long x; // 8 Example y; // 12 // 4 bytes padding }; static_assert(sizeof Example2 == 24, "Incorrect size"); // OK struct Example3 { unsigned char x[8]; // 8 unsigned char y[12]; // 12 // 4 bytes padding?? }; static_assert(sizeof Example3 == 24, "Incorrect size"); // ERROR
我使用64位系统与MSVC x64编译器,为何仅包含数组类型的结构体,其内存对齐值始终被计算为1?
原因解析
在MSVC x64环境下,结构体的对齐规则核心如下:
- 结构体的整体对齐要求,由其所有成员中对齐要求最高的成员决定。
- 数组类型的对齐要求,等于其元素类型的对齐要求。对于
unsigned char类型,其对齐要求为1(即无需强制对齐到更大的内存地址边界),因此不管数组长度是多少,unsigned char[N]的对齐要求始终是1。
回到你的代码:
- Example结构体:包含
int(对齐要求4)和char(对齐要求1),最高对齐要求为4。因此结构体整体需要对齐到4字节边界,char c后必须填充3字节,才能让x2对齐到4字节地址,最终总大小12(4+1+3+4),是4的倍数,符合要求。 - Example2结构体:包含
long long(对齐要求8)和Example(对齐要求4),最高对齐要求为8。Example的大小是12,12不是8的倍数,因此需要在y后填充4字节,让总大小24(8+12+4)满足8字节对齐要求。 - Example3结构体:两个成员都是
unsigned char数组,对齐要求均为1,因此结构体整体对齐要求为1。总大小直接是8+12=20,无需额外填充,所以static_assert(sizeof Example3 == 24)会触发错误。
内容的提问来源于stack exchange,提问作者Zaki
相关产品推荐
相关产品推荐

