码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 结构体的简单介绍(3)——结构体的内存对齐


    目录

    结构体的内存对齐:

    举例&提出疑问?

     内存对齐:

    对齐规则:

    偏移数:类似于数组的下标,指的是结构体每个成员的首个地址距离结构体起始位置的距离。

    用结构体内存对齐的图例示范:——使用以上文代码进行举例

    结构体嵌套的内存对齐 

    内存对齐的原因: 

    修改默认对齐数 



    结构体的内存对齐:

    举例&提出疑问?

    举例:

    1. struct S1
    2. {
    3. char c1;
    4. int i;
    5. char c2;
    6. };
    7. int main()
    8. {
    9. printf("%d\n",sizeof(struct S1));
    10. return 0;
    11. }

    以上代码是寻求一个结构体在内存中所占的字节大小。

    按照平常的逻辑理论,这里的结构体大小理论上说,应该是六个字节,因为成员c1占一个字节,成员i占四个字节,成员c2占一个字节,所以加在一起一共是6个字节。

    但答案真是如此吗?

    结果算出的是12个字节。

    而后,我又将结构体的成员顺序进行调换,结果还会是12个字节吗?

    1. struct S1
    2. {
    3. char c1;
    4. char c2;
    5. int i;
    6. };
    7. int main()
    8. {
    9. printf("%d\n",sizeof(struct S1));
    10. return 0;
    11. }

     通过运算,我们得知,最后得到的是八个字节。

    是不是很奇怪,明明成员内容都是一样的,只不过调换了顺序,最后结构体的字节大小却发生了改变,这是为什么?

    其实这是和结构体的内存对齐有关!

     内存对齐:

    概念:

    结构体的对齐本质上就是求结构体的大小。 

    对齐规则:

    1. 结构体的第⼀个成员对⻬到相对结构体变量起始位置偏移量为0的地址处

    2. 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

    对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩(变量的字节大小)的较⼩值。

     VS中默认的值为8

    Linux中没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩

    3. 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的 整数倍。

    4. 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。

    1. struct S1
    2. {
    3. char c1;
    4. int i;
    5. char c2;
    6. };
    偏移数:类似于数组的下标,指的是结构体每个成员的首个地址距离结构体起始位置的距离。

    用结构体内存对齐的图例示范:——使用以上文代码进行举例

     

    1. struct S1
    2. {
    3. char c1;
    4. char c2;
    5. int i;
    6. };

    上述代码也是如此:

    结构体嵌套的内存对齐 

    在掌握普通结构体的所占内存和对齐后,那么关于结构体嵌套的对齐值和内存该如何计算呢?

    1. struct S3
    2. {
    3. double d;
    4. char c;
    5. int i;
    6. };
    7. struct S4
    8. {
    9. char c1;
    10. struct S3 s3;
    11. double d;
    12. };
    13. printf("%d\n", sizeof(struct S4));

    先求第一个struct S3的所占内存:

     再求struct S4所占的内存:

     

     

    内存对齐的原因: 

    1. struct S
    2. {
    3. char c;
    4. int i;
    5. };

    假设以上是一段内存,前面一段是不用内存对齐的模式,后面一段是使用内存对齐的模式。

    二者看似毫无关系,且我们还觉得第二个模式还会浪费内存。

    但是,内存对齐其实是一种那空间换取时间的操作。

    为什么呢?这其实是和编译器的读取有关,vs编译器是32位机器,所以读取字节是一次读四个,而后要当你的结构体第一个成员是char第二个成员是int 时,且不进行对齐那么要读两次内存。

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

    修改默认对齐数 

    1. #include
    2. #pragma pack(8)//设置默认对齐数为8
    3. struct s1
    4. {
    5. char c1;
    6. int i;
    7. char c2;
    8. };
    9. #pragma pack()//取消设置的默认对齐数,还原为默认

  • 相关阅读:
    代码整洁之道-读书笔记之对象和数据结构
    c语言:sprintf() 函数用法示例
    c++ 关于bfs和dfs的相对统一写法
    属性和特征的区别
    Leetcode -2
    2012-07《信息资源管理 02378》真卷解析,逐题解析+背诵技巧
    博云入选国家级专精特新「小巨人」名单!
    【SpringBoot学习】44、SpringBoot 集成 Elasticsearch-7.6 实战
    赫夫曼树、赫夫曼编码
    2020华数杯全国大学生数学建模竞赛C题-脱贫帮扶绩效评价(五)(附MATLAB和SPSS代码)
  • 原文地址:https://blog.csdn.net/2301_76445610/article/details/132716760
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号