作者:聂勇 欢迎转载,请保留作者信息并说明文章来源!
数据结构对齐其实涉及到两个概念:数据对齐(data alignment)和数据结构填充(data structure padding)。计算机以块为单位(在32位系统中,以4 bytes为单位)对内存进行数据读写,因为这样可以提升CPU处理的性能。另外,为了数据对齐,需要在部分数据的尾部插入一些无意义的数据进行填充。
数据对齐规则 | data alignment rules
每个平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这个系数。
1、 结构中的第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(对齐系数,数据成员的自身长度) 的倍数。
2、数据成员完成各自对齐之后,结构本身也要进行对齐。
数据对齐长度 | data alignment length
Microsoft (Visual C++), Borland/CodeGear (C++Builder), Digital Mars (DMC) and GNU (GCC)在32位x86平台中默认的对齐长度如下:
数据类型 | 对齐长度 | 备注 |
---|---|---|
char | 1 byte | |
short | 2 bytes | |
int | 4 bytes | |
long | 4 bytes | |
float | 4 bytes | |
double | Windows:8 bytes Linux:4 bytes (编译时增加可选参数 -malign-double 为8 bytes对齐) |
|
long double | Visual C++:8 bytes (待验证) C++Builder / DMC:10 bytes (待验证) GCC:12 bytes(待验证) |
|
pointer | 4 bytes |
在64位x86平台与32位x86平台有以下类型的默认的对齐长度不同:
数据类型 | 对齐长度 | 备注 |
---|---|---|
long | 8 bytes | |
double | 8 bytes | |
long double | Visual C++:8 bytes (待验证) GCC:16 bytes |
|
pointer | 8 bytes |
实例 | example
源码
|
|
运行结果
sizeof(a1)=24
0x7fffbd59e0c0 0x7fffbd59e0c1 0x7fffbd59e0c4 0x7fffbd59e0c8 0x7fffbd59e0d0
1 3 4 8
sizeof(a2)=32
0x7fffbd59e0a0 0x7fffbd59e0a4 0x7fffbd59e0a8 0x7fffbd59e0b0 0x7fffbd59e0b8
4 4 8 8
sizeof(a3)=16
0x7fffbd59e090 0x7fffbd59e091 0x7fffbd59e092 0x7fffbd59e094 0x7fffbd59e098
1 1 2 4
sizeof(a4)=24
0x7fffbd59e070 0x7fffbd59e078 0x7fffbd59e080 0x7fffbd59e081 0x7fffbd59e084
8 8 1 3
内存示意图
说明:
- 斜线部分表示填充区域
- 上述代码在RedHat 5.7 b4bit系统中编译和运行,其默认的对齐系数是8 bytes
提示:
- 当struct本身是一个struct或union中的成员时,其对齐系数是struct中最大长度的成员的长度。
- 为了节省内存,占用内存小的成员放在结构的前面,占用内存大的成员放在结构的后面。