字节对齐知识整理

什么是字节对齐

在计算机中,数据都是以byte作为基本单位,理论上数据存储的时候,可以以任何地址起始(数据顺序的一个一个存放),但是实际情况中,为了cpu的效率考虑,数据在存储的时候,起始地址也会存在一定的排列规律,这就是字节对齐。

准则

  • 在普通位置时,存放数据的首地址,能够整除该数据类型。

举例说明:我们定义两个变量。

char a;
int b;

其中a的地址为:
在这里插入图片描述
b的地址为:
在这里插入图片描述
按照我们思维方式,变量a,b之间存储的地址应该紧挨着,但是为什么会出现这种情况,这就是字节对齐。
我们仔细一看就会发现,a的起始地址可以整除a变量的大小(char 一个字节),b的起始地址能够整除b变量的大小(short两个字节),满足准则一。

  • 在结构体中,结构体变量的首地址能够被其最宽数据类型成员的大小所整除。
    首先什么是最宽数据类型呢?最宽数据类型就是,在结构体中,占有空间最大的字节数。

例如:

struct Test
{
	int a;
	int b;
	char c;
};

在这里插入图片描述
该结构体中的最宽数据类型为int(4字节),因此该结构体的首地址必须整除4。

我们发现,结构体中存在一些内存没有利用,如果我们的运行内存很小,避免编译器对我们进行字节对齐,我们需要主动告诉编译器,通过#pargma pack(n)告诉编译器我们想要对齐的字节数是多少。

举例:

struct Test
{
	char a;
	int b;
	char c;
};

默认字节对齐:大小为12
在这里插入图片描述
我们使用#pragma pack(n)规定字节对齐大小
在这里插入图片描述
那么我们在自己设置对齐大小以后,编译器底层是如何进行处理的呢?
我们规定字节对齐大小的时候,编译器首先会判断当前字节大小与规定的字节大小的值,取一个交小的值。
例如:
在这里插入图片描述
上述代码字节对齐的过程:

  1. 首先程序的首地址一定是4的整数倍,准则二。
  2. 将第一个成员a,放入内存中。比较a类型的大小与设置具体数值,取较小值。min(sizeof(char),2) = 1,char类型为1个字节。则a的地址需要整除1。
    在这里插入图片描述
  3. 其次存放第二个成员b。min(sizeof(int),2) = 2,所以b的首地址需要整除2,则b需要想下偏移一格。
    在这里插入图片描述
  4. 接下来放入第三个成员c,方法与a类似。
    在这里插入图片描述
    但是上面的字节大小命名是7,为什么我们运行出来结果是8呢?因为还有一个注意事项。
    结构体的大小必须是N = min(sizeof(最大参数类型),对齐参数)的整数倍。
    还是上面的例子:
    最大参数类型:int ,对齐参数 :2,因此N = min(sizeof(int),2)。所以结构体的大小需要能够整除2,当不够的时候,需要在最后补充。因此最后的结构为:
    在这里插入图片描述
    因此结果就是8
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值