C++ 内存对齐

内存对齐 两条规则 :

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。

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值