C语言,关于字节对齐的一些问题

字节对齐,依据的是当系统要访问特定类型的变量时,必须在特定的内存地址访问,这就要求各种类型的变量按照一定的规则在空间上排列,而不是顺序的逐个排放。其本质就是,字节对齐可以提升存取效率,也就是空间换时间

为什么要字节对齐?

之前博主有研究过这个字节对齐相关的问题,欢迎大家来一同讨论!
链接直通车:STM32解决读写Flash失败进入HardFault的问题

每个平台对数据存放的对齐要求都不同,如果不按照适合该平台的数据存放对齐要求,会造成存取效率上的损失。比如某个平台每次读取数据时都是从偶地址开始的,如果一个int类型(32位系统)变量存放在偶地址开始的地方,那么一个读周期就能读出这32bit数据,而如果该变量存放在奇地址开始的地方,那么就需要两个读周期,并且要对这两次读出的结果进行高低字节拼凑才能得出这32bit数据,明显在读取效率上就低了很多。

举个例子来说明这个字节对齐的问题

背景知识:
1、基础数据类型的自身对齐值(32位系统)
char类型自身对齐为1字节,short类型自身对齐为2字节,int、float、long类型自身对齐均为4字节,double类型自身对齐为8字节。

2、结构体或类的自身对齐值
其成员中自身对齐值最大的值。

3、指定对齐值
通过预编译指令 #pragma pack (value)来指定对齐值的大小value,取消自定义对齐值使用 #pragma pack()。

4、数据成员、结构体和类的有效对齐值
其自身对齐值和指定对齐值中较小的那个值。

例子1:如下两个结构体A、B

struct A
{
	char a;
	short b;
	int c;
};
struct B
{
	short b;
	int c;
	char a;
};

请问上面两个结构体的大小分别是多少?
答:对于结构体A和结构体B,a是char类型,占用1字节;b是short类型,占用2字节;c是int类型,占用4字节。因此结构体A和结构体B的自身对齐值为4字节。又因为结构体类型数据是按照顺序存储结构逐个向后排列的,因此结构体A的大小为8字节,结构体B的大小为12字节。其对应的存储方式如下图。
在这里插入图片描述 在这里插入图片描述
例子2:为C、D结构体指定对齐值

#pragma pack(2) //指定2字节对齐
struct C
{
	char a;
	int b;
	short c;
};
#pragma pack() //取消指定对齐,恢复缺省对齐

#pragma pack(1) //指定1字节对齐
struct D
{
	char a;
	int b;
	short c;
};
#pragma pack() //取消指定对齐,恢复缺省对齐

请问上面两个结构体的大小分别是多少?
答:对于结构体C,由于其自身对齐值为4字节,而指定对齐值为2字节,所以该结构体的有效对齐值为较小的2字节,因此结构体C的大小为8字节。对于结构体D,同理可以得知大小为7字节。其对应的存储方式如下图。
在这里插入图片描述 在这里插入图片描述
总结,整个程序在给每个变量进行内存分配时都遵循字节对齐原则,虽然这会造成内存空间的浪费,但是却能换来程序执行效率的提升。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王鸽子

你的鼓励都是我前进的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值