要搞定如何正确地计算一个结构体的大小,我们就要深刻理解结构体内存对齐规则;

结构体内存对齐规则:

1.结构体的第一个成员永远在结构体起始位置偏移量为0的位置;

2.结构体成员从第二个成员开始,总是放在偏移量为一个对齐数的整数倍处;

对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值
Linux----没有默认对齐数;
VS---默认对齐数是8;
3.结构体的总大小必须是各个成员的对齐数中最大那个对齐数的整数倍;
4.如果嵌套了结构体的情况:
嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套的结构体的对齐数)的整数倍;

下面我们用练习列题来加深对结构体内存对齐规则的理解:

讲解: c1从起始位置偏移量为0的地方开始,占一个字节;

i 的大小是4,VS默认对齐数是8,取其小数4为对齐数,要放在偏移量为4的整数倍处,所以从偏移量为4开始放4个字节,

c2的大小是1,对齐数为1,放在对齐数的整数倍,所以放在接下来位置即可,占用1个字节

此时总大小是9;

又因为:

最大的对齐数是4,其往下找的最小整数倍数字是12;

所以这个结构体的总大小是12;(浪费3个字节空间)

列题2 :

嵌套情况讲解:

c1从起始位置开始,占一个字节;

s3是嵌套的结构体,同上述列题算出大小是16,其中最大对齐数是8,所以从偏移量为8开始用内存,占用16个字节;

d的大小是8,对齐数是8,放在偏移量为一个对齐数(8)的整数倍处,最近的就是24,所以从偏移量是24的位置放8个字节,最后放到偏移量为31的位置,所以总大小是32;

(每个(包含嵌套结构体成员)的对齐数中的最大对齐数就是8,32也是8的倍数,所以此结构体总大小是32);

接下来我们再来探讨:为什么存在内存对齐?

大部分的参考资料都是如是说的:

1. 平台原因(移植原因)

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

2. 性能原因

数据结构(尤其是栈)应该尽可能地在自然边界上对齐。

原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总的来说 :结构体的内存对齐是拿 空间 来换取 时间 的做法。
那在设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
答案: 让占用空间小的成员尽量集中在一起
此时我们设计时候就应该这样设计 :
S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别。

总结:

要学会计算结构体的大小,就要深刻理解结构体内存对齐规则,然后结合列题,(上面我讲解了两道不同情况的经典列题),解一通百,方可真正掌握结构体大小计算方法;

最重要的还是结合理论多练习 ~

【C语言】一文搞定如何计算结构体的大小----结构体内存对齐规则相关推荐

  1. C/C++ 结构体成员在内存中的对齐规则(转载)

    这几天在看王艳平的<windows 程序设计>,第5章讲解了MFC框架是怎么管理窗口句柄到窗口实例之间的映射,用到了两个类CPlex和CMapPtrToPtr,用于管理内存分配的类(避免因 ...

  2. 语言结构体在内存的分布_结构体内存对齐,这篇文章给你彻底搞会!(干货收藏)...

    脚本之家 你与百万开发者在一起 公众号:C语言编程 作者:薛定谔的coding猫 一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上 ...

  3. 一文搞懂结构体内存对齐

    结构体声明 以及结构体变量创建 为什么会有内存对齐 如何计算内存对齐 在现实生活中 为了描述复杂个体 如 书本 人 单一的数据类型已无法满足我们的需要 这时候 自定义类型 结构体 孕育而生 结构是一些 ...

  4. c#往结构体里面读数据_结构体内存对齐,这回给你彻底搞会!

    一.内存对齐的原因  1.平台原因(移植原因):一些资料上是这样说的,"不是所有的硬件平台都能访问任意地址上的任意数据:某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常 ...

  5. 室友利用一把王者的时间就学会了【C语言结构体内存对齐】

    文章目录 一.什么是结构体内存对齐? 二.结构体的对齐规则 结构体内存对齐规则的具体应用 三.为什么会存在内存对齐 总结 提示:以下是本篇文章正文内容,下面案例可供参考 一.什么是结构体内存对齐? 从 ...

  6. 谈谈C语言中结构体内存对齐问题及其offsetof宏的基本使用

    前言 在C语言中,变量在内存中摆放的位置是有一定的规则的,不是想摆放到哪里就摆放到哪里,就比如常见的局部变量在栈区,全局变量在全局区等方式:而今天我们聊的结构体里面的成员变量呀,也是有一定的规则存放在 ...

  7. 【C语言】结构体内存对齐

    前言: 作者简介:爱吃大白菜1132 人生格言:纸上得来终觉浅,绝知此事要躬行   如果文章知识点有错误的地方不吝赐教,和大家一起学习,一起进步!   如果觉得博主文章还不错的话,希望三连支持! 如今 ...

  8. 第10章结构体01——结构体字节大小的计算

    1.该篇笔记详见C提高笔记(传智播客) 文章目录 博文01:(常考面试题) 三步解决C语言中struct字节对齐问题,结构体的字节大小问题 第1步.先确定结构体实际对齐单位, 第2步.除结构体的第一个 ...

  9. 结构体内存对齐,默认对齐数,结构体传参

    我们先来计算一下结构体内存的大小 现在我们计算一下stu1和stu2每个成员内存偏移是多少. 在介绍偏移量之前,我们先简单介绍一下offsetof(是一个宏),它是用来计算结构体成员相较于起始位置的偏 ...

最新文章

  1. akka框架——异步非阻塞高并发处理框架
  2. EJBCA使用之注册用户及创建证书
  3. linux下加载qdm找不到驱动,Linux下共享文件夹的设置方法
  4. Html爱情表白动画
  5. Python机器学习实践:决策树判别汽车金融违约用户
  6. MediaPlay播放Stream时出现error 38等错误的原因
  7. Magic Maze dfs + dp
  8. 常用应用层传输协议和端口
  9. 月薪 1 万和 10 万的人,到底差在哪儿?
  10. gdb调试出现optimized out解决方法
  11. 【SpringBoot 框架】- SpringBoot 配置文件,深入浅出mysql第三版pdf百度云
  12. mysql front连接_如何成功用MySQL-Front连接MySQL?
  13. HTML入门笔记13-HTML中font标签
  14. Android应用逆向——最好用的两个无源码调试器
  15. 开发必备技术--docker(使用篇)
  16. Android Support Library介绍
  17. STM32+ESP8266使用MQTTAT固件连接云
  18. 2018上海区块链国际周倒计时,汇聚全球意见领袖的技术盛会
  19. FlexiGrid插件的使用(ASP项目)
  20. 信息学奥赛一本通 2036:【例5.3】开关门

热门文章

  1. 分组表管理之保存分组表数据
  2. python⾯向对象学员管理系统
  3. k近邻算法之 k值的选择
  4. python自定义包或模块在Linux服务器导入错误的解决办法
  5. 人工智能-离散数学-消解原理
  6. DeepLabv3:语义图像分割
  7. 用于道路目标检测的少镜头学习
  8. OpenCV 新版 4.5.1 发布!
  9. jQuery API之each、children、index的使用
  10. C++Builder及VC的库相互调用