C 语言:内存字节对齐详解[转载] 收藏
一、什么是对齐,以及为什么要对齐:
1. 现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型的变量的访问
可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,
这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这
就是对齐。
2. 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些
特定类型的数据只能从某些特定地址开始存取。其他平台可能没有这种情况, 但是最常见
的是如果不按照适合其平台的要求对数据存放进行对齐,会在存取效率上带来损失。比如
有些平台每次读都是从偶地址开始,如果一个 int 型(假设为 32 位)如果存放在偶地址开
始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要
2 个读周期,并对两次读出的结果的高低 字节进行拼凑才能得到该 int 数据。显然在读取效
率上下降很多。这也是空间和时间的博弈。
二、对齐的实现
通常,我们写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对
齐策略。当然,我们也可以通知给编译器传递预编译指令而改变对指定数据的对齐方法。
但是,正因为我们一般不需要关心这个问题,所以因为编辑器对数据存放做了对齐,而我
们不了解的话,常常会对一些问题感到迷惑。最常见的就是 struct 数据结构的 sizeof 结果,
出乎意料。为此,我们需要对对齐算法所了解。
对齐的算法:
由于各个平台和编译器的不同,现以本人使用的 gcc version 3.2.2 编译器(32 位 x86 平台)
为例子,来讨论编译器对 struct 数据结构中的各成员如何进行对齐的。
设结构体如下定义:
struct A {
int a;
char b;
short c;
};
结构体 A 中包含了 4 字节长度的 int 一个,1 字节长度的 char 一个和 2 字节长度的 short 型
数据一个。所以 A 用到的空间应该是 7 字节。但是因为编译器要对数据成员在空间上进行
对齐。
所以使用 sizeof(strcut A)值为 8。
现在把该结构体调整成员变量的顺序。
struct B {
char b;
int a;
short c;
};
这时候同样是总共 7 个字节的变量,但是 sizeof(struct B)的值却是 12。
下面我们使用预编译指令#pragma pack (value)来告诉编译器,使用我们指定的对齐值来取
评论0
最新资源