一、内存对齐的原因

 1.平台原因(移植原因):一些资料上是这样说的,“不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些特定地址处取某些特定的数据,否则就会抛出硬件异常”。也就是说在计算机在内存读取数据时,只能在规定的地址处读数据,而不是内存中任意地址都是可以读取的。

2.效率原因:正是由于只能在特定的地址处读取数据,所以在访问一些数据时,对于访问未对齐的内存,处理器需要进行两次访问;而对于对齐的内存,只需要访问一次就可以。其实这是一种以空间换时间的做法,但这种做法是值得的。

二、结构体内存对齐规则

1.第一个成员在结构体变量偏移量为0 的地址处,也就是第一个成员必须从头开始。

2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 为编译器默认的一个对齐数与该成员大小中的较小值。vs中默认值是8 Linux默认值为4(当然可以通过#pragma pack()修改),但修改只能设置成1,2,4,8,16。

3.结构体总大小为最大对齐数的整数倍。(每个成员变量都有自己的对齐数)

4.如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。

三、内存对齐规则应用

这四条规则可能不太好理解,下面我们就通过几个实例进行讲解:

例题1

结果是8,我们来分析一下为什么结果是 8。c1是char型,占一个字节,第一个成员即 c1 在结构体变量偏移量为0 的地址处。

c2是char型,占一个字节,要对齐到对齐数的整数倍的位置。对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值,vs中默认值是8,取较小值1,char类型的对齐数是1,所以对齐到1 的整数倍,那就是偏移量为1开始的地址空间。

i是int类型,占四个字节,要对齐到对齐数的整数倍的位置。int类型的对齐数就是 4,所以对齐到4 的整数倍。

内存分布图 1

例题2

结果是12,来看一下过程。c1是char型,占一个字节,对应到结构体变量偏移量为0 的地址处。i是int型,占四个字节,对齐数就是4,对齐到4的整数倍位置处,即偏移量为4开始的地址空间。

c2是char型,占一个字节,对齐到1 的整数倍,那就是下一个地址空间,对齐到偏移量为8的地址空间。结构体总大小为最大对齐数的整数倍,所以为对齐数4的整数倍,现在已经用了9个字节的空间,那么总大小就是12个字节空间。所以输出结果是12。

内存分布图 2

例题3

结果是32,我们来看一下分析:根据上面讲解的容易得出struct S3占16个字节。那我们来看一下struct S4的大小,struct S4中有三个成员变量,第一个char型,占一个字节,对齐到偏移量为0的地址处。

第二个成员是结构体嵌套使用,结构体S3变量s3,刚才已经得出占16个字节,所以第二个成员对齐数是16,又因为对齐数是编译器默认数与成员对齐数中的较小值,vs默认对齐数是8,取较小值8,所以对齐到偏移量为8的地址空间处。

第三个成员是double型,占8个字节,对应到8的整数倍即偏移量24的地址处。结构体总大小是最大对齐数8的整数倍,所以是32。

内存分布图3 

本文授权转载自公众号“C语言编程”,作者薛定谔的coding猫

-END-

推荐阅读

【01】stm32几种低功耗模式的实现和差别【02】长见识了:STM8、STM32可以超频吗?【03】STM32:从菜鸟到牛人就是如此简单!【04】干货 | STM32单片机按键消抖和FPGA按键消抖大全【05】学习STM32的一些经验分享免责声明:整理文章为传播相关技术,版权归原作者所有,如有侵权,请联系删除

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

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

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

  2. printf打印结构体_工程师:这道题80%初学者都没做对!你确定搞懂结构体内存对齐了?...

    这是工程师面试后的实际经历-- 这道经典.易错的关于C语言结构体内存对齐的题目,你真的会吗: 求32bit环境下以下结构体所占的字节数:typedef struct test_struct{ char ...

  3. Golang——结构体创建与初始化、结构体与数组、结构体与切片、结构体与map、结构体作为函数参数、结构体方法、结构体方法继承

    结构体: 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 结构体可以很好的管理一批有联系的数据,使用结构体可以提高程序的易读性,类似于Java的类一样 不能在结构体直接赋值 字段名必须唯一 ...

  4. golang 结构体struct、数组、结构体数组 定义与赋值 、json string转struct

    文章目录 1.结构体struct 1.1 声明结构体 1.2 初始化结构体 以及 传参 2. 结构体数组.append 3. 接口返回 含数组的结构体 常用写法 json string转struct ...

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

    要搞定如何正确地计算一个结构体的大小,我们就要深刻理解结构体内存对齐规则: 结构体内存对齐规则: 1.结构体的第一个成员永远在结构体起始位置偏移量为0的位置: 2.结构体成员从第二个成员开始,总是放在 ...

  6. c语言结构体反射解析,C语言结构体解析

    我们知道定义一个数组就等于定义了多个相同类型的变量,它们的类型是一样的.有时有这样的需求,如果我想保存一些信息,但每个信息类型不一定相同,这时该怎么办?我们就可以自己定义一类型,而这个类型,就是结构体 ...

  7. c语言结构体与共同体课件,《结构体与共同体》PPT课件.ppt

    <<结构体与共同体>PPT课件.ppt>由会员分享,可在线阅读,更多相关<<结构体与共同体>PPT课件.ppt(44页珍藏版)>请在装配图网上搜索. 1 ...

  8. 通过结构体某个成员的地址计算结构体首地址 (转)

    最近在CU论坛上有很多人在问这样一个问题:给出一个结构体成员的地址计算该结构体的起始地址.其实这个题我之前也没有接触过,据说内核代码中有这样用的,但还没有看到.不过觉得这个题的解决方法还是有一定技巧的 ...

  9. 【精华文】C语言结构体特殊情况分析:结构体指针 / 基本数据类型指针,指向其他结构体

    参考链接:Structure pointer pointing to different structure instance 注:可以查看此篇的问题和唯一的回复,那是相对正确的,不要看comment ...

最新文章

  1. linux tar 提示 time stamp xxx in the future 解决方法
  2. 屏幕输出语句_2.2 数据输入与输出
  3. 代码重构的实战经验和那些坑
  4. 堆栈的生长方向和空栈满栈的区别
  5. 小白学数据分析------日活跃人数分析
  6. 如何寻找无序数组中的第K大元素?
  7. 移动端输入框弹出键盘控制
  8. 使用WebService与Oracle EBS进行集成(上)
  9. 万年自学党聊聊如何选择编程学习资源?
  10. termux apache php,要啥自行车之Termux:将我们的(Android)安卓手机打造成全能的服务器...
  11. 小别墅样式_6款三层小别墅样式,各风格特色图纸为农村自建量身打造
  12. python识别文字tesseract
  13. jQuery和$、jQuery(function(){})和(function(){})(jQuery)
  14. 《统计学》第八版贾俊平第十一章一元线性回归知识点总结及课后习题答案
  15. echarts 中国地图设置高亮省份
  16. 百度网盘加速下载方法——系统自带的提速模式和积分模式区别
  17. 京东页面html前台代码,京东页面代码
  18. DICOMRT:XXX Target Volume,各种目标体积浅析
  19. 基于MVC的简易图形编辑器
  20. 什么是API接口平台?作用是什么?

热门文章

  1. Quartus ii与Modelsim-altera 6.5b联调前仿真
  2. 图像处理基本算法 形状特征
  3. PGM中置信传递、和—积算法
  4. JavaScript解析顺序和变量作用域
  5. 导出Android手机应用apk
  6. 深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS
  7. 细说C#多线程那些事 - 线程同步和多线程优先级
  8. springmvc学习笔记(17)-上传图片
  9. 桌面支持--电脑出现临时账户--解决办法
  10. mvn -U clean eclipse:clean eclipse:eclipse