struct的内存对齐原则(含有位域情况)
前提:没有pragma pack宏
【1】数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员(正在放的这个变量)大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
——(注意:数组只按照类型大小,不是数组大小)——
【2】结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
【3】收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
使用位域的主要目的是压缩存储,C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。
例如
struct node{
char onStatus:1;
char offStatus:1;
char allNums:6;
}
其大致规则为:
【1】 如果相邻位域字段的类型相同,且其位宽之和小于这个类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
【2】 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
【3】 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
【4】 如果位域字段之间穿插着非位域字段,则不进行压缩;
【5】 整个结构体的总大小为最宽基本类型成员大小的整数倍。