struct结构体大小的计算方法
1)第一个成员处在偏移地址0的地方
2)每个成员按其类型大小和pack参数中较小(编译器默认#pragma pack(4) 4字节对齐)的一个进行对齐
偏移地址必须能被对齐参数整除
结构体成员的对齐参数为结构体成员内部最大的那个
3)结构体的总长度必须为所有对齐参数的整数倍
编译器默认4字节对齐,#pragma pack(x) 能够改变编译器的默认对齐方式
下面几个例子是结构体大小的计算过程
#include <stdio.h>
#pragma pack(4)
struct Test1
{ //对齐参数 偏移地址 大小
char c1;//1 0 1
short s; //2 2 2
char c2;//1 4 1
int i; //4 8 4
};
#pragma pack()
//总长度为12 是所有对齐参数的整数倍
#pragma pack(4)
struct Test2
{ //对齐参数 偏移地址 大小
char c1;//1 0 1
char c2;//1 1 1
short s; //2 2 2
int i; //4 4 4
};
#pragma pack()
//总长度为8 是所有对齐参数的整数倍
#pragma pack(4)
struct Test3
{ //对齐参数 偏移地址 大小
char c1;//1 0 1
short s; //2 2 2
char c2;//1 4 1
};
#pragma pack()
//总长度为6 是所有对齐参数的整数倍
int main()
{
printf("sizeof(Test1) = %d\n", sizeof(struct Test1));
printf("sizeof(Test2) = %d\n", sizeof(struct Test2));
printf("sizeof(Test3) = %d\n", sizeof(struct Test3));
return 0;
}
下面是一个包含结构体成员的结构体大小计算
#include <stdio.h>
#pragma pack(8) //按照8字节对齐
struct S1
{ //对齐参数 偏移地址 大小
short a; //2 0 2
long b; //4 4 4
};
//总长度为8 是所有对齐参数的整数倍
struct S2
{ //对齐参数 偏移地址 大小
char c; // 1 0 1
struct S1 d; // 4 4 8
double e; // 8 16 8
};
//结构体成员的对齐参数为结构体成员内部最大的那个 对于S1来说 长度最大的成员为long 对齐参数为4
//总长度为24 是所有对齐参数的整数倍
#pragma pack()
int main()
{
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
return 0;
}
gcc中的运行结果如下
8
20
为什么不是24呢? 因为在gcc中暂不支持8字节对齐
所以实际上struct S2的对齐方式为
struct S2
{ //对齐参数 偏移地址 大小
char c; // 1 0 1
struct S1 d; // 4 4 8
double e; // 4 12 8
};
//得到实际长度为20
在VC中可以得到
8
24