内存对齐 两条规则 :
1.对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度)的倍数。
2.在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
!important 1)注意不要把上面两者搞混淆一个是 成员的偏移量,一个是整个结构体。 2)对齐自身数据成员时都是自身数据成员整数倍原因最大double 为8,而系统默认为8所以 min (pragma ,自身)一般等于自身。
看一个小程序:
看上面程序:
#include <iostream>
using namespace std;
struct S1
{
short int a;
float b;
int c;
char d;
};
struct S2
{
int a2;
S1 st1;
double b2;
short int c2;
};
int main(){
cout<<" sizeof(float) "<<sizeof(float)<<" sizeof(int) "<<sizeof(int)<<" sizeof(short int) "<<sizeof(short int)<<endl;
cout<<" sizeof(double) "<<sizeof(double)<<" sizeof(char) "<<sizeof(char)<<endl;
S1 st1;
cout<<"&st1 "<<(&st1)<<endl;
cout<<"short int &st1.a "<<(&st1.a)<<endl;
cout<<"float &st1.b "<<(&st1.b)<<endl;
cout<<"int &st1.c "<<(&st1.c)<<endl;
cout<<"char &st1.d "<<(&st1.d)<<endl;
cout<<"sizeof(st1) " <<sizeof(st1)<<endl;
cout<<"----------------------------------------------"<<endl;
S2 st2;
cout<<"&st2 "<<(&st2)<<endl;
cout<<"int &st2.a2 "<<(&st2.a2)<<endl;
cout<<"S1 &st2.st1 "<<(&st2.st1)<<endl;
cout<<"double &st2.b2 "<<(&st2.b2)<<endl;
cout<<"short int &st2.c2 "<<(&st2.c2)<<endl;
cout<<"sizeof(st2) " <<sizeof(st2)<<endl;
return 0;
}
输出结果为:
sizeof(float) 4 sizeof(int) 4 sizeof(short int) 2
sizeof(double) 8 sizeof(char) 1
&st1 0012FF70
short int &st1.a 0012FF70
float &st1.b 0012FF74 // (应为float 为4 偏移量必须为4的倍数)
int &st1.c 0012FF78
char &st1.d 烫烫?
sizeof(st1) 16 // (2(short int )+2(空)+4(float)+ 4(int) +1(char)+ 3(空))//后面3个空的是为了满足第二个规则 最大4的倍数。
----------------------------------------------
&st2 0012FF48
int &st2.a2 0012FF48
S1 &st2.st1 0012FF4C //(因为S1 最大成员int 4 所以便宜 4的倍数)
double &st2.b2 0012FF60 //(0012FF4C-0012FF5C 为 st1 0012ff5c-0012ff60为了补偿了double 8 的倍数 )
short int &st2.c2 0012FF68
sizeof(st2) 40 // (4(int )+S1(16)+4(空)+8(double) +2(short int) +6(空 补齐为double 8的倍数 满足第二个规则))
Press any key to continue
3.内存为什么要对齐可以看该博文的解说: http://www.cppblog.com/snailcong/archive/2009/03/16/76705.html
把上面程序改一下: pargma pack 由默认8变为2。
#include <iostream>
using namespace std;
#pragma pack(2)
struct S1
{
short int a;
float b;
int c;
char d;
};
struct S2
{
int a2;
S1 st1;
double b2;
short int c2;
};
int main(){
cout<<" sizeof(float) "<<sizeof(float)<<" sizeof(int) "<<sizeof(int)<<" sizeof(short int) "<<sizeof(short int)<<endl;
cout<<" sizeof(double) "<<sizeof(double)<<" sizeof(char) "<<sizeof(char)<<endl;
S1 st1;
cout<<"&st1 "<<(&st1)<<endl;
cout<<"short int &st1.a "<<(&st1.a)<<endl;
cout<<"float &st1.b "<<(&st1.b)<<endl;
cout<<"int &st1.c "<<(&st1.c)<<endl;
cout<<"char &st1.d "<<(&st1.d)<<endl;
cout<<"sizeof(st1) " <<sizeof(st1)<<endl;
cout<<"----------------------------------------------"<<endl;
S2 st2;
cout<<"&st2 "<<(&st2)<<endl;
cout<<"int &st2.a2 "<<(&st2.a2)<<endl;
cout<<"S1 &st2.st1 "<<(&st2.st1)<<endl;
cout<<"double &st2.b2 "<<(&st2.b2)<<endl;
cout<<"short int &st2.c2 "<<(&st2.c2)<<endl;
cout<<"sizeof(st2) " <<sizeof(st2)<<endl;
return 0;
}
运行结果为:
sizeof(float) 4 sizeof(int) 4 sizeof(short int) 2
sizeof(double) 8 sizeof(char) 1
&st1 0012FF74
short int &st1.a 0012FF74
float &st1.b 0012FF76
int &st1.c 0012FF7A //这个据0012FF74 不再是 4的倍数而只是2的倍数因为把pragma pack 变成了2.
char &st1.d 烫?
sizeof(st1) 12
----------------------------------------------
&st2 0012FF58
int &st2.a2 0012FF58
S1 &st2.st1 0012FF5C
double &st2.b2 0012FF68
short int &st2.c2 0012FF70
sizeof(st2) 26
Press any key to continue
4.union的大小取决于它所有的成员中,占用空间最大的一个成员的大小
看下面程序:
#include <iostream>
using namespace std;
union u1
{
double a;
int b;
};
union u2
{
char a[13];
int b;
};
union u3
{
char a[13];
char b;
};
int main(){
cout<<sizeof(u1)<<endl; // 8
cout<<sizeof(u2)<<endl; // 16
cout<<sizeof(u3)<<endl; // 13
return 0;
}
运行结果为:
8
16 //为16 是 因为有一个int 要,struct 大小整个要为 sizeof(int) 大小整数倍。
13
Press any key to continue
5.对于结构体中的结构体成员,不要认为它的对齐方式就是他的大小,看下面的例子:
struct s1
{
char a[8];
};
struct s2
{
double d;
};
cout<<sizeof(s1)<<endl; // 8
cout<<sizeof(s2)<<endl; // 8
s1,s2 大小都为8,但是s1 的对齐方式为1,s2 的对齐方式为8。