结构体对齐
1 例子
运行以下程序:
运行结果:
为什么会不一样呢?
答案:结构体对齐造成的。
2 内存布局
Figure 1. 我眼中的内存空间布局
学了计算机组成原理,了解了内存的基本单元是一个字节,内存可以随机寻址,于是乎我天真的认为内存就是一个字节型的容器,基本单位是单个字节。
Figure 2. cpu眼中的内存空间布局
内存读写的真正访问者cpu不是这么想的。cpu是根据内存访问粒度(memory access granularity,下文简写成MAG)来读取内存,MAG就是cpu一次内存访问操作的数据量,具体数值依赖于特定的平台,一般是2byte、4byte、8byte。
因此,程序员和cpu看待内存空间布局是存在差异的。编译器对我们的代码进行隐式的内存对齐(当然它能做的只是帮程序中的数据进行内存对齐,至于直接用指针去访问内存,它是不会管的)。
3 四个基本概念
- 数据类型自身的对齐值:即数据类型长度值
- 结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
- 默认对齐值:编译器默认的一个对齐数
- 指定对齐值:#pragma pack (value)时的指定对齐值value。
- 数据成员、结构体和类的有效对齐值:自身对齐值和指定(或默认)对齐值中小的那个值。
下表是Windows XP/DEV-C++和Linux/GCC中基本数据类型的长度和默认对齐模数。
char |
short |
int |
long |
float |
double |
long long |
long double |
||
Win-32 |
长度 |
1 |
2 |
4 |
4 |
4 |
8 |