结构体成员变量的字节对齐
结构体成员变量的字节对齐
- 编译器版本(
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 许可协议。转载请注明来自 科海拾零!