在默认情况下,为了方便对结构体和类中数据元素的访问和管理,当结构体或类内的数据元素的长度都小于机器字长时,就以结构体或类中最长的数据元素为对齐单位。也就是说,结构体或类的长度一定是最长数据元素的整数倍。如果结构体或类内存在长度大于机器字长的数据元素,那么就以机器的字长为对齐单位。结构体或类中类型相同的连续元素将在连续的空间,和数组保持一致。
例如:(机器字长为32位)
struct{
short a1;
short a2;
short a3;
}A;
class B
{
public:
int a;
static int b;
B();
~B();
};
struct{
float a;
int b;
char c;
}C;
求sizeof(A),sizeof(B),sizeof(C);
对于A,short类型变量占2个字节,因此sizeof(A)为6;对于B,静态变量是存放在全局数据区的,而sizeof计算栈中分配的大小,因此sizeof(B)为4;对于C,考虑到数据对齐,float大小为4,int大小为4,char大小为1,因此sizeof(C)为12。
原理:为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理。在默认情况下,VC规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。
各成员变量在存放的时候根据在结构中出现的顺序依次申请空间,同时按照上面的对齐方式调整位置,空缺的字节VC会自动填充。同时VC为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数,所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。
struct
{
char dda;
double dda1;
float dd;
}A;
int main()
{
cout<<sizeof(A)<<endl;
return 0;
}
char占1个字节,double占8个字节,float占4个字节,因此结构体对齐默认按8字节对齐。sizeof(A)=1+(7)+8+4+(4)=24.其中,括号中的数字都是VC自动填充的字节数。
另外,需要补充的是,如果是嵌套类(结构体),则使用上面的规则时,地址对齐时,依据的是嵌套类所拥有的数据成员里占用空间类型最大的类型,而不是考虑整个嵌套类。
class ab
{
char *pa;
void get_ia();
struct cd
{
double da;
int ib;
}abc;
};
这时,sizeof(ab)=4+(4)+8+4+(4)=24.
在默认情况下,为了方便对结构体和类中数据元素的访问和管理,当结构体或类内的数据元素的长度都小于机器字长时,就以结构体或类中最长的数据元素为对齐单位。也就是说,结构体或类的长度一定是最长数据元素的整数倍。如果结构体或类内存在长度大于机器字长的数据元素,那么就以机器的字长为对齐单位。结构体或类中类型相同的连续元素将在连续的空间,和数组保持一致。