内存对齐详解
C/C++内存对齐
一、什么是字节对齐,为什么要对齐?
现代计算机中内存空间都是按照 byte 划分的,从理论上讲似乎对任何类型
的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时
候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空
间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些
平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的
CPU
在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编
程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按
照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失。比如有些
平台每次读都是从偶地址开始,如果一个 int 型(假设为 32 位系统)如果存放
在偶地址开始的地方,那 么一个读周期就可以读出这 32bit,而如果存放在奇
地址开始的地方,就需要 2 个读周期,并对两次读出的结果的高低字节进行
拼凑才能得到该 32bit
数 据。显然在读取效率上下降很多。
二、请看下面的结构:
struct MyStruct
{
double dda1;
char dda;
int type
};
对结构 MyStruct 采用 sizeof 会出现什么结果呢?sizeof(MyStruct)为多少呢?也
许你会这样求:
sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int)=13
但是当在 VC 中测试上面结构的大小时,你会发现 sizeof(MyStruct)为 16。你知
道为什么在 VC
中会得出这样一个结果吗?
其实,这是 VC 对变量存储的一个特殊处理。为了提高 CPU 的存储速度,VC
“
”
对一些变量的起始地址做了 对齐 处理。在默认情况下,
VC 规定各成员变量
存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用
的字节数的倍数。
下面列出常用类型的对齐方式(vc6.0,32 位系统)
。
类型
对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char
偏移量必须为 sizeof(char)即 1
的倍数
int
偏移量必须为 sizeof(int)即 4
的倍数
float
偏移量必须为 sizeof(float)即 4
的倍数
double