最近又回归到了C,在看一些C的书籍,下面是一个以为对C字节对齐讲得比较详细的文章。html
原文:C语言字节对齐问题–详细讲解面试
PS:(腾讯实习面试有问到字节对齐有关问题:2015届腾讯实习校园面试题)数组
1、概念
对齐跟数据在内存中的位置有关。若是一个变量的内存地址正好位于它长度的整数倍,他就被称作天然对齐。好比在32位cpu下,假设一个整型变量的地址为0×00000004,那它就是天然对齐的。
2、为何要字节对齐
须要字节对齐的根本缘由在于CPU访问数据的效率问题。假设上面整型变量的地址不是天然对齐,好比为0×00000002,则CPU若是取它的值的话须要 访问两次内存,第一次取从0×00000002-0×00000003的一个short,第二次取从0×00000004-0×00000005的一个 short而后组合获得所要的数据,若是变量在0×00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为 char,而后组合获得整型数据。而若是变量在天然对齐位置上,则只要一次就能够取出数据。一些系统对对齐要求很是严格,好比sparc系统,若是取未对 齐的数据会发生错误,举个例:
char ch[8];
char *p = &ch1;
int i = *(int *)p;
运行时会报segment error,而在x86上就不会出现错误,只是效率降低。
3、正确处理字节对齐
对于标准数据类型,它的地址只要是它的长度的整数倍就好了,而非标准数据类型按下面的原则对齐:
数组 :按照基本数据类型对齐,第一个对齐了后面的天然也就对齐了。
联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每一个数据类型都要对齐。
好比有以下一个结构体:spa
struct stu{
char sex;
int length;
char name[10];
};
struct stu my_stu;.net
因为在x86下,GCC默认按4字节对齐,它会在sex后面跟name后面分别填充三个和两个字节使length和整个结构体对齐。因而咱们sizeof(my_stu)会获得长度为20,而不是15.
4、attribute选项
咱们能够按照本身设定的对齐大小来编译程序,GNU使用attribute选项来设置,好比咱们想让刚才的结构按一字节对齐,咱们能够这样定义结构体. 设计
struct stu{
char sex;
int length;
char name[10];
}attribute ((aligned (1)));
struct stu my_stu;
则sizeof(my_stu)能够获得大小为15。
上面的定义等同于
struct stu{
char sex;
int length;
char name[10];
}attribute ((packed));
struct stu my_stu;code
attribute((packed))得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐.
5、何时须要设置对齐
在设计不一样CPU下的通讯协议时,或者编写硬件驱动程序时寄存器的结构这两个地方都须要按一字节对齐。即便看起来原本就天然对齐的也要使其对齐,以避免不一样的编译器生成的代码不同.htm