当前位置: 首页 > article >正文

结构体内存对齐与位段

1.对齐规则:

1.结构体的第一个成员对齐到结构体变量的起始位置(偏移量为0处)。

2.其它成员要对齐到对齐数的整数倍的地址处(编译器默认对齐数(vs默认为8,gcc没有默认只看变量)与该成员变量所占字节的较小值。)

3.结构体总大小为最大对齐数的整数倍

4.如果嵌套了结构,则该嵌套的结构体的最大对齐数是自己成员中最大对齐数的那一个的整数倍处。第3条规则就改为了还要看结构体里面的成员的最大对齐数,和非嵌套的那部分的成员,所有成员中对齐数最大的那一个

例子:

1.   

struct stu {

char c1;

char c2;

int n;

}

  

最终总共消耗了8个字节的空间,刚好是最大对齐数 4(int n存放对应的),所以如果用

sizeof(struct stu) 会等于8

2.

struct stu {

char c1;

int n;

char c2;

}

与刚刚那个略微有一点点不一样的是占了9个字节,不为4的整数倍,所以要转化为整数倍;所以

sizeof(struct stu)会等于12;


2.为什么要进行内存对齐?

2.1平台原因:

某些平台需要数据出现在特定的位置处;

2.2性能原因:

实际上就是一个空间换取时间的过程,32位的机器,一次就读取4个字节(32个bit),当你将结构体中的数据连续存放时,会出现   char int int int | int这种情况,需要重新再读取一遍前面的三个int,会降低性能,但是对齐的话,可以直接跳过,就能刚好读到起始的位置;

在上面的两个例子中可以得知,第二种浪费的空间就会比较多;所以,为了节省空间,我们在定义结构体的时候应该尽量让占空间小的变量集中在一起。


3.修改默认对齐数:

#pramga pack()想改多少就填多少


4.结构体的位段

注意的事项:

1.位段的成员必须是char(整型)  int  unsigned int或者signed int

2.位段是不跨平台的

struct stu {

int a:2;

int b:5;

int c:10;

int d:30;

};

冒号后面的代表需要多少个比特位;

4.1

位段的内存存放方式(vs x86环境下):

一开始先在01地址(假设)处生成一个int类型的的空间,首先分配2个比特的空间给a,再分配5个比特给b,接着再分配10个比特给c,现在就占了32个比特位中的17个比特了,已经放不下d的了,所以需要浪费这部分空间,在05地址处再生成一个新的int空间,同理分配30个空间;

4.2 

对不跨平台原因进行部分探究:

1.int在不进行位段的时候不会考虑有无符号整型(char正常也需要考虑),正常就是signed,但是在跨平台的时候就需要考虑这个问题;

2.不同平台对类型的字节设置是不同的;

3.位段中的成员在内存中是左到右还是右到左是不确定的;

4.位段在上面那个例子中int大于了剩余空间,是否会进行消耗,也是不确定的。


http://www.kler.cn/a/327322.html

相关文章:

  • SpringBoot总结
  • 使用nossl模式连接MySQL数据库详解
  • 无线迷踪:陈欣的网络之旅
  • ES6笔记
  • 【Oracle篇】掌握SQL Tuning Advisor优化工具:从工具使用到SQL优化的全方位指南(第六篇,总共七篇)
  • go环境搭建
  • 基于 Qwen2.5-0.5B 微调训练 Ner 命名实体识别任务
  • Java数据结构链表(LinkedList详解)
  • Vue3 Typescript 前端页面5min后无操作自动退出至登录页面
  • Windows上面搭建Flutter Android运行环境
  • cmd下的管理员权限闪退 原理分析
  • 【Rockchip系列】官方函数:drm_buf_alloc
  • 【Kotlin基于selenium实现自动化测试】初识selenium以及搭建项目基本骨架(1)
  • 华为OD机试 - 超级玛丽通过吊桥的走法 - 动态规划(Python/JS/C/C++ 2024 E卷 200分)
  • 数据结构——计数、桶、基数排序
  • 深入探索 PyTorch 在机器学习中的应用
  • 观测云对接 SkyWalking 最佳实践
  • Springboot中yml文件不生效原因分析及解决
  • 【C++篇】启航——初识C++(下篇)
  • 滚雪球学Oracle[7.1讲]:Oracle云数据库
  • 如何从 Windows 11/10/8.1/8/7 中恢复已删除的视频
  • 前端导出页面PDF
  • rust的nutyp验证和validator验证数据的方法
  • MySQL | group by 用法
  • 牛客周赛 Round 62
  • 828华为云征文|部署个人文档管理系统 Docspell