一. 结构体默认的字节对齐一般满足三个准则:
- 1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
- 2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
- 3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)
举例:
1 typedef struct B { 2 char a1; 3 short int a2; 4 int a3; 5 double d; 6 }BB;
1. sizeof(BB)=16
1 typedef struct A { 2 double d; 3 char a1; 4 int a3; 5 short int a2; 6 }AA;
2. sizeof(AA)=24
二. 特殊情况:嵌套结构体
- 展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
- 结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。
- 满足以上原则再把子结构体当作一个整体与其他数据进行相加计算大小。
举例:
1 typedef struct C { 2 long int b2; 3 short int b1; 4 AA a ; 5 //double d; 6 //char a1; 7 //int a3; 8 //short int a2; 9 }CC;
3. sizeof(CC)=32
1 typedef struct D { 2 long int b2; 3 AA a; 4 // double d; 5 // char a1; 6 // int a3; 7 // short int a2; 8 short int b1; 9 }DD;
3. sizeof(DD)=40
三. 运行实例
1 #include <iostream> 2 using namespace std; 3 4 typedef struct A { 5 double d; 6 char a1; 7 int a3; 8 short int a2; 9 }AA; //24 10 11 typedef struct B { 12 char a1; 13 short int a2; 14 int a3; 15 double d; 16 }BB; //16 17 typedef struct C { 18 long int b2; 19 short int b1; 20 AA a ; 21 }CC; //32 22 typedef struct D { 23 long int b2; 24 AA a; 25 short int b1; 26 }DD; //40 27 int main(void) { 28 cout<<sizeof(AA)<<" "<<sizeof(BB)<<" "<<sizeof(CC)<<" "<<sizeof(DD)<<endl; 29 return 0; 30 }