字节对齐

为什么要字节对齐

如何处理字节对齐

  1. 数据类型自身的对齐值:为指定平台上基本类型的长度。对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
  2. 结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
  3. 指定对齐值:#pragma pack (value)时的指定对齐值value。
  4. 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。
    结构体的字节对齐
    当数据类型为结构体时,编译器可能需要在结构体字段的分配中插入间隙,以保证每个结构元素都满足它的对齐要求。第一个数据变量的起始地址就是数据结构的起始地址。结构体的成员变量要对齐排放(对于非对齐成员需要在其前面填充一些字节,保证其在对齐位置上),结构体本身也要根据自身的有效对齐值圆整(就是结构体总长度需要是结构体有效对齐值的整数倍),此时可能需要在结构末尾填充一些空间,以满足结构体整体的对齐—-向结构体元素中最大的元素对齐。

来自 https://blog.csdn.net/cclethe/article/details/79659590

struct test { char a; short b; int c; long d; };

alt text
struct test2 { int a; long b; char c; };
alt text
结构体嵌套地情况,结构体对齐算法思想:深度优先填充。

先对齐内层结构体:对每个数据成员计算其defaultLen、memberLen和offset;
再遍历每个数据成员时计算:对于基本数据类型成员defaultLen=memberLen;对于结构体成员defaultLen等于它的所有成员的最大的memberLen;遍历时对成员的memberLen进行累加,得到当前成员的offsetLen;
运用对齐及填充规则:在当前结构体成员前填充padLen个字节;
struct test1 { int a; long b; }; struct test4 { char a; struct test1 b; int c; };
alt text

更改C编译器的缺省字节对齐方式

在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:
• 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
• 使用伪指令#pragma pack (),取消自定义字节对齐方式。
另外,还有如下的一种方式:
attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。
• __attribute
((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。
字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐可以有效地节省存储空间。

字节对齐可能带来的隐患

alt text

如何查找与字节对齐方面的问题

如果出现对齐或者赋值问题首先查看
1. 编译器的big little端设置
2. 看这种体系本身是否支持非对齐访问
如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作