结构体的内存对齐规则

前言

结构体是一种自定义类型,其中包含了许多不同类型的变量,我们称这些值为成员变量,那么这种自定义类型的大小该怎么计算呢?这才是我们今天讨论的重点问题。

结构体内存对齐规则

要想计算结构体的大小,首先得了解结构体的内存对齐规则。

  • 第一个成员在与结构体变量偏移位为0的地址处
  • 其他成员变量要对齐到对齐数整数倍的地址处

对齐数 = 编译器默认的对齐数(VS为8、Linux为4) 与 该成员大小的较小值

  • 结构体的总大小为最大对齐数的整数倍
  • 如果有嵌套结构体的情况,嵌套的结构体对齐到自己最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数的整数倍。

下面我们看两个例子:
在这里插入图片描述

存在内存对齐的原因

计算结构体大小的时候,为什么会存在结构体的内存对齐规则呢?

  • 平台原因: 不是所有硬件平台都能访问任意地址空间上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  • 性能原因: 数据结构应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问只需要一次。

总的来说结构体内存对齐就是以空间时间的做法

结构体的设计

我们通过两个例子来理解不同设计的区别:

设计一:
typedef struct test{
  char c1;
  int a;
  char c2;
}Test;                 

printf("%d\n", sizeof(Test));  运行结果:12

设计二:
typedef struct test{
  char c1;
  char c2;                      
  int a;
}Test;

printf("%d\n", sizeof(Test));  运行结果:8

我们既要满足对齐又要节省空间,所以让占用空间小的成员尽量集中在一起

结构体的传参

函数传参的时候,参数是需要压栈的,会有时间和空间上的系统开销

如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。

结构体传参的时候需要传结构体的地址

修改默认对齐数

结构体在对齐方式不合适的时候,我们通过一个宏可以更改默认对齐数。

#pragma pack(对齐数): 设置默认对齐数
#pragma pack( ): 取消设置的默认对齐数,还原为系统默认对齐数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值