结构体为什么要4字节对齐

sizeof与struct——求结构体大小的计算方法
sizeof浅析(一)——求结构体大小 这篇文章讲了sizeof求结构体大小的计算方法,并给出可以套用的准则:

一、存储变量时地址要求对齐,编译器在编译程序时会遵循两条原则:
(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。

二、 对于嵌套的结构体,需要将其展开。对结构体求sizeof时,上述两种原则变为:
(1)展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
(2)结构体大小必须是所有成员大小的整数倍,这里所有成员计算的是展开后的成员,而不是将嵌套的结构体当做一个整体。

为什么?
但是编译器为什么要这么做,以下是我的理解。

为什么要对齐?
因为在32位操作系统(虽然64位操作系统,但是为了保证兼容性,编程仍然主要考量32位)中,数据总线是32位,地址总线是32位。
地址总线是32位,意味着寻址空间是按4递增的;数据总线32位意味着一次可读写4byte。
考虑这样一个结构体

struct stu1  
{   
   char c1;   
   int i;  
   char c2;  
} 

在这里插入图片描述
不对齐就意味着,当我们执行stu1.i 时,需要读取内存两次。而对齐后,就只需要读取一次,众所周知,I/O操作是很耗时的,编译器做出对齐的选择也就好理解。

为什么不完全按照4字节对齐的?
既然对齐可以避免上述的问题,为什么不将所有存储小于4byte的数据类型(char, short等)统统按4byte对齐呢?
考虑这样一个结构体

struct stu2  
{   
   char c;   
   short s;
   int i; 
   double d; 
}

在这里插入图片描述
为什么编译器采用B方案,而不采用A方案?
还是因为32数据线一次读取4个字节,
采用方案A,读取stu2.c,或者stu2.s,要一次读取4个byte,再舍弃无关内存的数据。
采用方案B,读取stu2.c,或者stu2.s,也是要一次读取4个byte,再舍弃无关内存中的数据。
同样的I/O操作,相比之下,明显方案B更节省内存。

补充: 如上图中,所示8字节的数据类型,比如double, long long,必须要读取两次内存。

明白这两点,再回看上面结构体大小的计算方法,就简单多了,也不用死记烂背了。
另外,写代码时也知道怎样节省内存了(虽然大多数时间不用考虑这点)。

  • 10
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值