成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e;
长度为24,已经可以被8(成员e按8字节对齐)整除.一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****11111111
*/
三、针对字节对齐,我们在编程(www.cppentry.com)中如何考虑?
如果在编程(www.cppentry.com)的时候要考虑节约空间的话,那么我们只需要假定结构的首地址是0, 然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变量按照类型大小从小到大声明,尽量减少中间的填补空间。还有一种就是为了以空间换取时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做法是显式的插入reserved成员:
struct A
{
char a;
char reserved ; //使用空间换时间
int b;
};
reserved成员对我们的程序没有什么意义,它只是起到填补空间以达到字节对齐的目的,当然即使不加这个成员通常编译器也会给我们自动填补对齐,我们自己加上它只是起到显示的提醒作用。
四、字节对齐可能带来的隐患
代码中关于对齐的隐患,很多是隐式的。比如在强制类型转换的时候。例如:
unsigned int i = 0x12345678;
unsigned char *p = NULL;
unsigned short *p1 = NULL;
p=&i;
*p=0x00;
p1=(unsigned short*)(p+1);
*p1=0x0000;
最后两行代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定。在X86上,类似的操作只会影响效率,但是在MIPS或者sparc上,可能就是一个error,因为它们要求字节必须对齐。
五、如何查找与字节对齐方面的问题
如果出现对齐或者赋值问题首先查看
1.编译器设置的对齐值
2.看这种体系本身是否支持非对齐访问
3.如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。