|
1
2
3
4
5
6
|
struct
MyStruct
{
double
dda1;
char
dda;
int
type;
};
|
对齐方式(变量存放的起始地址相对于结构的起始地址的偏移量)
Char
偏移量必须为sizeof(char)即1的倍数
int
偏移量必须为sizeof(int)即4的倍数
float
偏移量必须为sizeof(float)即4的倍数
double
偏移量必须为sizeof(double)即8的倍数
Short
偏移量必须为sizeof(short)即2的倍数
默认的对齐方式
|
1
2
3
4
5
6
|
struct
MyStruct
{
double
dda1;
char
dda;
int
type;
};
|
|
1
2
3
4
5
6
|
struct
MyStruct
{
char
dda;
double
dda1;
int
type;
};
|
typedef struct bb
{
int id; //[0]....[3] 表示4字节
double weight; //[8].....[15]
float height; //[16]..[19],总长要为8的整数倍,仅对齐之后总长为[0]~[19]为20,补齐[20]...[23]
}BB;
typedef struct aa
{
int id; //[0]...[3]
double score; //[8]....[15]
short grade; //[16],[17]
BB b; //[24]......[47] (因为BB内部最大成员为double,即8的整数倍开始存储)
char name[2]; //[48][49] 50个字节,凑六个,成为8的倍数
}AA;
int main()
{
cout<<sizeof(AA)<<" "<<sizeof(BB)<<endl;
return 0;
}
输出结果为56(补位凑成8的倍数) 24
struct s1
{
char a[8];
};
struct s2
{
double d;
};
struct s3
{
s1 s;
char a;
};
struct s4
{
s2 s;
char a;
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
cout<<sizeof(s3)<<endl; // 9
cout<<sizeof(s4)<<endl; // 16;
所以,在自己定义结构体的时候,如果空间紧张的话,最好考虑对齐因素来排列结构体里的元素。
编译器中提供了#pragma pack(n)来设定变量以n字节对齐方式。//n为1、2、4、8、16...
n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,即该变量所占用字节数的整数倍;第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。
结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须为n的倍数。
所以在上面的代码前加一句#pragma pack(1),
则代码输出为bb:(0~3)+(4~11)+(12~15)=16; aa:(0~1)+(2~5)+(6~13)+(14~15)+(16~31)=32,也就是说,#pragma pack(1)就是没有对齐规则。
再考虑#pragma pack(4),bb:(0~3)+(4~11)+(12~15)=16; aa:(0~1)+(4~7)+(8~15)+(16~17)+(20~35)=36
4、 32位和64位系统的区别
5、联合体的sizeof
共用体表示几个变量共用一个内存位置,在不同的时间保存不同的数据类型和不同长度的变量。在union中,所有的共用体成员共用一个空间,并且同一时间只能储存其中一个成员变量的值。当一个共用体被声明时, 编译程序自动地产生一个变量, 其长度为联合中元类型(如数组,取其类型的数据长度)最大的变量长度的整数倍,且要大于等于其最大成员所占的存储空间。
union foo
{
char s[10];
int i;
} ;
union mm{
char a;//元长度1 1
int b[5];//元长度4 20
double c;//元长度8 8
int d[3]; 12
};
foo的内存空间的长度为12,是int型的3倍,而并不是数组的长度10。若把int改为double,则foo的内存空间为16,是double型的两倍。
同理,
sizeof(mm)=8*3=24;
本文详细解释了在不同系统及编译器设置下,结构体成员变量如何按特定规则对齐,及其对结构体大小的影响。并通过具体示例介绍了结构体内嵌结构体时的对齐规则,以及使用#pragma pack(n)指令时的对齐变化。
733

被折叠的 条评论
为什么被折叠?



