结构体对齐的几个问题浅析
1.关于结构体对齐
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器,它每次读写内存的时候都从某个8倍数的地址开始,一次读出或写入8个字节的数据,假如软件能保证double类型的数据都从8倍数地址开始,那么读或写一个double类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8字节内存块上。
2.第一个问题
charshortintlongdoublelong doubleWindows长度124488模数124488Linux长度1244812模数124444以上面的例子来说,sum_a = 10,数据成员s1放在相对偏移0处,之前不需要填充字节;s2同样不需要填充;数据成员s3为了内存对齐,根据“结构体大小的计算方法和步骤”中第二条原则,其对齐模数是4,之前需填充2个字节,所以sum_b=12,因为12是4的倍数,所以最终结果是12.
3.第二个问题
#include "stdio.h"union{struct student{unsigned char s1:1;unsigned char s2:2;unsigned short s3:2;}x;unsigned short c;unsigned int d;}v;int main(){v.d=0;v.x.s1=0;v.x.s3=2;printf("%d\n",v.x);printf("%d\n",sizeof(v));return 0;}这段代码在VS2005中运行结果是131072 , 4
在GCC中的运行结果是16 , 4
131072 = (100000000000000000)b,在VS2005中,输出这样的答案,是因为对于short s3,已经使用了结构体对齐。
16 = (10000)b,说明在GCC中,对于short s3并没有进行结构体对齐,只是运用了位结构体的规则。
这里的区别需要注意一下。。。另外希望能有一个统一的标准,要不然这样确实很麻烦哎。