字节对齐就是数据在内存中的位置。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。
需要字节对齐的根本原因在于CPU访问数据的效率问题。假如整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据,如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。
对于标准数据类型,它的地址只要是它的长度的整数倍就行了,而非标准数据类型按下面的原则对齐:
1. 数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
2. 联合 :按其包含的长度最大的数据类型对齐。
3. 结构体: 结构体中每个数据类型都要对齐。
struct stu{
char sex;
int length;
char name[10];
};
这个里面sex是1个字节,然后遇到length的时候,需要在sex后添加3个空字节,因为length占4个字节,而在name占10个字节之后,变为18个字节,并不对齐,所以添两个空字节。变为20个字节。
__attribute__
选项
这个是改变对齐方法的,如下例子:
struct stu{
char sex;
int length;
char name[10];
}__attribute__ ((aligned (1)));
这个是一共变成了15个字节,因为aligned
改变了自然对齐字节为1个字节。所以整体缩小了。
同样下面的声明:
struct stu{
char sex;
int length;
char name[10];
}__attribute__ ((packed));
这个也是15个字节。packed
让结构体使用最小的对齐方式。
在设计不同CPU的通信协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都需要按一字节对齐。即使看起来本来就自然对齐的也要使其对齐,以免不同的编译器生成的代码不一样.
原文地址:http://blog.csdn.net/alps1992/article/details/46347795