C++ 内存对齐

来源:互联网 发布:c语言的架构 编辑:程序博客网 时间:2024/06/09 18:42

内存对齐 两条规则 :

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。