现在的位置: 首页 > 综合 > 正文

C++中结构体的sizeof

2019年10月15日 ⁄ 综合 ⁄ 共 3837字 ⁄ 字号 评论关闭
  • 为什么要地址对齐?
  •  *  我们在访问内存时,如果地址是按4字节对齐,则访问效率会高很多。
  •  *  这个问题的原因在于访问内存的硬件电路。一般情况下,地址总线总是按照对齐后的地址来访问。
  •  *  例如你想得到0x00000001开始的4字节内容,系统首先需要以0x00000000读4字节,
  •  *  然后从中取得3字节,然后在用0x00000004作为开始地址,获得下一个四字节,
  •  *  在从中得到第一个字节,两次组合出你想得到的内容。但是如果地址一开始就是对齐到
  •  *  0x00000000,则系统只要一次读写即可。
  • 所以,为了性能考虑,编译器会做地址对齐。
  • 地址对齐的原则:
  • 每个基本类型有自己默认的对齐值。 然后可以通过#pragma pack(2) 设置编译器的默认对齐值。取两者最小的一个作为最终对齐值。
  • 若没有#pragma pack(2) 设置,那么只看基本类型自己的对齐值。
  • 总之: 在允许的情况下,尽量依次填充,但是需要保证(32位系统)
  •    1  char,bool只从X地址处开始存储;
  •    2  short只从2X地址出开始存储;
  •    3  int,float,long只从4X地址处开始存储;
  •    4  double只从8X地址处开始存储;

下面是列子:

#include <iostream>
using namespace std;

//sizeof(union1) = 16
union union1 {
	long i;		//4
	int x[4];	//16
	char ch;	//1
};

//sizeof(union2) = 16
union union2{
	char a[13];
	int i;	//由于int的存在,使得union按照四个字节来对其了
};

//sizeof(union3) = 13
union union3{
	char a[13];
	char i;
};

/////////////// 对比node1和node2 ///////////
struct node1{	//24
	int j;		//4
	double f;	//8	
	int i;		//4
};
	
struct node2{	//16
	int i;		//4
	int j;		//4
	double f;	//8	
};

/////////////// 对比node3和node4 ///////////
struct node3{	//32(注意)
	char i;		//1
	int d[5];	//20
	double f;	//8	
};

struct node4{	//40
	int d[5];	//20
	double f;	//8	
	int i;		//4
};

///////////////////////////////////////////
struct node5{	//32(注意)
	char d[10];	//10
	double f;	//8	
	int i;		//4
};

struct node6{	//20
	char d;		//1
	int f;		//4
	char i[10];	//10
};
//}__attribute__((aligned (1)));
///////////////////////////////////////
struct node7{	//12
	char x1;	//1
	short x2;	//2
	float x3;	//4
	char x4;	//4
};

#pragma pack(1) //指定按照1字节对齐
struct node8{	//8
	char x1;	//1
	short x2;	//2
	float x3;	//4
	char x4;	//1
};
#pragma pack()	//恢复缺省的字节对齐设置
////////////////////////////////////////
struct node9{	//20
	char ch,*p;	//1,4
	union{		//4
		short a,b;	
		unsigned int c:2,d:1;
	}u;
	bool f;		//1
	struct node9 *next;	//4
};

//测试字节对齐
void test2(){
	int size;
	struct node1 n1;
	struct node2 n2;
	struct node3 n3;
	struct node4 n4;
	struct node5 n5;
	struct node6 n6;
	struct node7 n7;
	struct node8 n8;
	struct node9 n9;
	//栈生长的方向与地址增长方向相反,所以a的地址比b的地址大四字节
	int a = 1,b = 2,c=3;
	int *p = &b;
	printf("%d\n",*(p+1));	//1
	
	//测试union和struct的大小(后者会地址对齐,前者仍然输出16)
	printf("union1:%d\n",sizeof(union union1));	//16
	printf("union2:%d\n",sizeof(union union2));	//16
	printf("union3:%d\n",sizeof(union union3));	//13

	//测试结构体的地址对齐
	printf("************************\n");
	printf("n1:%d\n",sizeof(n1));			
	printf("%ld\n",(unsigned long)&n1.j);	
	printf("%ld\n",(unsigned long)&n1.f);
	printf("%ld\n",(unsigned long)&n1.i);

	printf("************************\n");
	printf("n2:%d\n",sizeof(n2));		
	printf("%ld\n",(unsigned long)&n2.i);
	printf("%ld\n",(unsigned long)&n2.j);
	printf("%ld\n",(unsigned long)&n2.f);

	printf("************************\n");
	printf("n3:%d\n",sizeof(n3));		
	printf("%ld\n",(unsigned long)&n3.i);
	printf("%ld\n",(unsigned long)&n3.d);
	printf("%ld\n",(unsigned long)&n3.f);

	printf("************************\n");
	printf("n4:%d\n",sizeof(n4));		
	printf("%ld\n",(unsigned long)&n4.d);
	printf("%ld\n",(unsigned long)&n4.f);
	printf("%ld\n",(unsigned long)&n4.i);

	printf("************************\n");
	printf("n5:%d\n",sizeof(n5));		
	printf("%ld\n",(unsigned long)&n5.d);
	printf("%ld\n",(unsigned long)&n5.f);
	printf("%ld\n",(unsigned long)&n5.i);

	printf("************************\n");
	printf("n6:%d\n",sizeof(n6));		
	printf("%ld\n",(unsigned long)&n6.d);
	printf("%ld\n",(unsigned long)&n6.f);
	printf("%ld\n",(unsigned long)&n6.i);

	printf("************************\n");
	printf("n7:%d\n",sizeof(n7));		
	printf("%ld\n",(unsigned long)&n7.x1);
	printf("%ld\n",(unsigned long)&n7.x2);
	printf("%ld\n",(unsigned long)&n7.x3);
	printf("%ld\n",(unsigned long)&n7.x4);

	printf("************************\n");
	printf("n8:%d\n",sizeof(n8));
	printf("%ld\n",(unsigned long)&n8.x1);
	printf("%ld\n",(unsigned long)&n8.x2);
	printf("%ld\n",(unsigned long)&n8.x3);
	printf("%ld\n",(unsigned long)&n8.x4);

	printf("************************\n");
	printf("n9:%d\n",sizeof(n9));
	
}

int main(){
	int *ptr;
	test2();
	printf("************************\n");
	printf("char:%d\n",sizeof(char));		//1
	printf("short:%d\n",sizeof(short));		//2
	printf("int:%d\n",sizeof(int));			//4
	printf("long:%d\n",sizeof(long));		//4
	printf("float:%d\n",sizeof(float));		//4
	printf("double:%d\n",sizeof(double));	//8
	printf("pointer:%d\n",sizeof(ptr));		//4
	return 0;
}

 

 

抱歉!评论已关闭.