转自:http://blog.youkuaiyun.com/wzzyz/article/details/6743813
内存数据对齐:
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
2、 性能原因:经过内存对齐后,CPU的内存访问速度大大提升。
图一:
这是普通程序员心目中的内存印象,由一个个的字节组成,而CPU并不是这么看待的。
图二:

CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory accessgranularity(粒度)本人把它翻译为“内存读取粒度”。
假设CPU要读取一个int型4字节大小的数据到寄存器中,分两种情况讨论:
1、数据从0字节开始
2、数据从1字节开始
再次假设内存读取粒度为4。
图三:
当该数据是从0字节开始时,很CPU只需读取内存一次即可把这4字节的数据完全读取到寄存器中。
当该数据是从1字节开始时,问题变的有些复杂,此时该int型数据不是位于内存读取边界上,这就是一类内存未对齐的数据。
图四:

此时CPU先访问一次内存,读取0—3字节的数据进寄存器,并再次读取4—5字节的数据进寄存器,接着把0字节和6,7,8字节的数据剔除,最后合并1,2,3,4字节的数据进寄存器。对一个内存未对齐的数据进行了这么多额外的操作,大大降低了CPU性能。
我的理解:
1. 32位机,CPU每次访问都是按照4字节读取内存的,而且访问的起始地址为4的倍数。
2. 结构体
//8字节
struct A
{
int a;
char b;
short int c;
};
//12字节
struct B
{
char a;
int b;
short int c;
};
结构体中每个成员都要4字节对齐。
struct C
{
int a;
int b;
char c;
};
结构体C为12个字节,虽然9个字节也能满足各变量对齐要求,但是考虑到 C c[4]; 结构体数组的情况。
c[0]处于0-8, c[1] 9-17 这样导致结构体地址不能对齐,而结构体地址为首个变量的地址,即a地址,所以
a没有地址对齐。解决方法是:结构体大小也要为4的倍数,如果不是4的倍数,则在结构体后部填充。