今天做了两个关于位域的内存对齐的实验,看下图。
对于Stu, a跟b因为都是4位,所以会放在一个字节里,但是因为int本身是4个字节的,所以还是会用掉4个字节的空间,即便后面的成员是2个字节的short。同时因为结构的大小必须是最大成员长度的整数倍,所以可以看到short后面有俩字节的补齐。所以sizeof (Stu)是8.
Stu2是更有有趣的一种情况。前两个char占据一个字节,但是因为后面的是short,所以必须补一个字节以使得short起始位置是sizeof(short)的整数倍。而两个short各占四位也就是还是挤在了一个字节里。现在加上前面char的数据已经有了三个字节,所以还得填充一个字节以使得int能从整数倍位置开始。所以sizeof(Stu2)也是8.
结论,类型相同的成员会尝试放在一个sizeof(该类型)的内存块里,不管指定了占多少位,所使用的内存大小还是根据类型来的,位域只是影响到存取值。
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字
段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字
段将从新的存储单元开始,其偏移量为其类型大小的整数倍;(经测试此条好像仅限于char型,整型可以跨域存储)
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方
式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。