结构体成员变量的字节对齐
结构体成员变量的字节对齐
- 编译器版本(
MinGW及其衍生品,比如TDM-GCC可能不支持#pragma pack(n), n>1,参见 mingw-and-packed-struct-alignment-using-c11)
1
2
3
4
5 ❯ gcc --version
gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- 本文讨论的对齐属性
1
2
3
__attribute__((packed));
__attribute__((aligned(8)));
- 完整验证代码见文末
- 在 Linux 环境下
char占字节, int占字节, short占字节, long long占字节( long占字节( 位), 字节( 位))
实验 1
无全局的
#pragma pack(n)
实验结果如下
1 | struct test { // size = 15 |
注释中所标注的是结构体中每个成员变量所占内存空间的大小(如
- test:
__attribute__((packed))取消字节对齐,所有成员紧凑排列; - test1:
系统中,默认 字节对齐,则 char后填充字节, short后填充字节,总共占 字节; 位系统中,为了保证 long long字节对齐,要在 short后填充字节,总共占 字节; - test2:
__attribute__((aligned(8)));要求test2的起始地址是的倍数。 位系统中,按照 test1,结构体总共占字节。但考虑连续实例化 test2的情况,第一个起始地址是的倍数,占 字节,下一个的起始地址就不再是 的倍数,因此需要在末尾再填充 字节,总共占用 字节; 位系统中,按照 test1,结构体总共占字节。可以满足再实例化的结构体起始地址是 的倍数,不需要在末尾额外填充,总共占用 字节;
实验 2
1
实验结果如下
1 | struct test { // size = 15 |
全局的 #pragma pack(1) 表示默认紧凑排列,所以 test 和 test1 均占用 15 字节。
test2 中 __attribute__((aligned(8))); 要求起始地址
实验 3
1
实验结果如下
1 | struct test { // size = 15 |
全局的 #pragma pack(2) 表示默认按
- test:
__attribute__((packed))取消字节对齐,所有成员紧凑排列; - test1:按
字节对齐,则 char后需填充字节,总共占 字节; - test2:按
test1,总共占字节,可以满足再实例化的结构体起始地址是 的倍数,不需要在末尾额外填充,总共占 字节;
附录:完整实验代码
1 |
|
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 科海拾零!
评论