结构体大小

1、结构体大小由成员变量和偏移量相加而成;
2、其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处,整体大小也要能被对齐数整除

总对齐数: = 编译器默认的一个对齐数与该成员大小的较小值, 也就是min{编译器默认的对齐数成员变量大小的最大值},VS中默认的对齐数为8;

单个对齐数:该类型变量所占内存大小,char 对齐数是1 ,int 对齐数是4 , double 是8 , 32位指针类型是4 , 64位指针类型是8;

对齐原则分两步:

1、单个成员变量对齐(也就是说,单个变量的起始地址能被单个对齐数整除)
2、整体对齐(整体大小能被对齐数整除,若不能不整除,则增加偏移来填充)

相同的成员变量,因为声明位置不同,导致占用内存空间不同,看下面代码


void test6()
{
//总对齐数min{编译器默认的对齐数=8 ,成员变量大小的最大值double=8 } = 8
	struct node
	{
		//假设总体空间为all 
		double m;//8   double对齐数为8  ,此时all=8  [0:7]
		int a;//4           int 对齐数为 4        all=12 [8:11]
		char c;//1        char对齐数  1         all=13   [12]
		char b;//1        char对齐数  1        all=14    [13]
	};//16               **开始整体对齐,要能被整体对齐数整除,也就是能被8整除,14不能被8整除,+2=16 即可,所以all=16**

	struct node1
	{
		char c;		//1	 char对齐数  1         all=1
		int a;//4	       int对齐数  4  (char c 后空出三个字节,从第四个字节开始存放 int a)       all=8
		char b;			//1  char对齐数  1         all=9
		double m;//8    double对齐数为8  (char b 后空出7个字节,从第四个字节开始存放double m) ,此时all=24
	};//24     24能被8整除,所以整体不需要偏移

	cout << sizeof(node) << "---" << sizeof(node1) << endl;
}

单个成员变量对齐(也就是说,单个变量的起始地址能被单个对齐数整除)更加通俗的讲就是;double类型必须从被8整除的地址开始,int 必须从被4整除的地址开始,若起始地址不能被整除,则向后移动,直到能被整除,空出来的空间直接浪费,用空间换时间。

如果嵌套了结构体的情况,内层嵌套的结构体成员对齐到自己的最大对齐数的整数倍的地址,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

为什么要偏移
平台的原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取到某些特定类型的数据,否则抛出硬件异常。
性能的原因: 数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值