C语言-----结构体内存对齐

2023-05-16

结构体内存对齐规则:

  1. 第一个成员在结构体变量偏移量为0 的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值。vs中默认值是8 Linux默认值为4.
  3. 结构体总大小为最大对齐数的整数倍。(每个成员变量都有自己的对齐数)
  4. 如果嵌套结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。

内存对齐规则应用

接下来我们看一下具体怎么应用这几条规则??

struct S1
{
    char c1;
    char c2;
    int i;
};
printf("%d\n", sizeof(struct S1));

结果是8,我们来分析一下为什么结果是 8??
c1是char型,占一个字节,第一个成员即 c1 在结构体变量偏移量为0 的地址处。
c2是char型,占一个字节,要对齐到对齐数的整数倍的位置。对齐数 = 编译器默认的一个对齐数与该成员大小中的较小值,vs中默认值是8,取较小值1,char类型的对齐数是1,所以对齐到1 的整数倍,那就是偏移量为1开始的地址空间。
i是int类型,占四个字节,要对齐到对齐数的整数倍的位置。int类型的对齐数就是 4,所以对齐到4 的整数倍。
我们来看一下内存分布图:
这里写图片描述
那我们再来看一下这个输出结果是多少呢

struct S2
{
    char c1;
    int i;
    char c2;
};
printf("%d\n", sizeof(struct S2));

结果是12,来看一下过程?
c1是char型,占一个字节,对应到结构体变量偏移量为0 的地址处。
i是int型,占四个字节,对齐数就是4,对齐到4的整数倍位置处,即偏移量为4开始的地址空间。
c2是char型,占一个字节,对齐到1 的整数倍,那就是下一个地址空间,对齐到偏移量为8的地址空间。
结构体总大小为最大对齐数的整数倍,所以为对齐数4的整数倍,现在已经用了9个字节的空间,那么总大小就是12个字节空间。所以输出结果是12。

看一下内存分布图:
这里写图片描述
结构体也是可以嵌套使用的,那如果嵌套的话,大小是怎么判断的呢?

struct S3
{
    double d;
    char c;
    int i;
};
struct S4
{
    char c1;
    struct S3 s3;
    double d;
};
printf("%d\n", sizeof(struct S4));

结果是32,我们来看一下分析:
容易得出struct S3占16个字节。请读者自行分析,如果不会的话可以问我哦。
那我们来看一下struct S4的大小,struct S4中有三个成员变量,第一个char型,占一个字节,对齐到偏移量为0的地址处。第二个成员是结构体嵌套使用,结构体S3变量s3,刚才已经得出占16个字节,所以第二个成员对齐数是16,又因为对齐数是编译器默认数与成员对齐数中的较小值,vs默认对齐数是8,取较小值8,所以对齐到偏移量为8的地址空间。处。第三个成员是double型,占8个字节,对应到8的整数倍即偏移量24的地址处。
结构体总大小是最大对齐数16的整数倍,所以是32。
来看一下内存分布图:
这里写图片描述

为什么存在内存对齐呢?

  1. 平台原因(移植原因):
    不是所有的硬件平台都能访问任意地址的任意数据的;某些平台只能在某些地址处取某些特定类型的数据

  2. 性能原因:
    数据结构尤其是栈应该尽可能在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次访问内存;而对齐的内存访问仅需要一次访问。

    缺点:

    无可厚非:这必然会存在效率问题,这是一种以空间换时间的做法,但这种做法是值得的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言-----结构体内存对齐 的相关文章

随机推荐

  • 使用 GitHub Copilot 自动化测试

    代码完成并不是什么新鲜事 像 IntelliSense 这样的工具已经允许开发人员通过尝试自动完成他们正在编写的函数或语句的名称来提高工作效率 xff0c 但是可用的工具只有一定程度的实际 智能 可用 随着 GitHub 的 Copilot
  • 想让你的接口自动化测试更加有效? 这个统计方法必须掌握

    覆盖率概念 接口自动化测试是现代软件开发中不可或缺的一环 xff0c 它能够帮助开发团队自动化执行测试用例 xff0c 以快速而准确地发现并修复软件缺陷 而覆盖率统计则是在测试执行完成后 xff0c 帮助测试团队了解哪些代码路径被覆盖了 x
  • 大小端字节序详解

    目录 引文 大小端介绍 xff08 1 xff09 什么是大端小端 xff08 2 xff09 为什么有大端和小端 xff08 3 xff09 笔试题讲解 引文 在开始正文之前 xff0c 我想先问一下大家 xff0c 内存中是怎样存放一个
  • 【C库函数】strcat函数详解

    目录 strcat 函数原型 参数讲解 返回值详解 函数讲解 xff08 1 xff09 源字符串和目标字符串都必须以 39 0 39 结束 xff08 2 xff09 目标空间必须足够大 xff0c 能容纳下源字符串的内容 xff08 3
  • CAN协议

    CAN xff08 Controller Area Network xff09 是一种常见的串行总线通信协议 xff0c 用于在汽车 工业控制和其他应用中传输数据 它是一种高效 可靠 安全的通信协议 xff0c 具有广泛的应用 下面是CAN
  • 串口协议简介

    串口协议是一种基于串行通信的数据传输协议 它通过串口接口将数据以串行的方式传输 串口协议通常包括物理层 数据链路层和应用层三个部分 xff0c 其中物理层主要定义了串口接口的电气特性 xff0c 数据链路层定义了数据的传输方式和错误检测机制
  • CAN协议总线仲裁原理:数据发送权争夺

    CAN总线仲裁原理是指在多个CAN节点同时发送数据时 xff0c 如何避免冲突 并选择一个节点作为发送者 CAN总线的仲裁原理基于一个分布式仲裁机制 xff0c 它可以快速而可靠地确定哪个节点可以获得总线控制权 xff0c 从而发送数据 C
  • Spring整合JMS(一)——基于ActiveMQ实现

    1 1 JMS简介 JMS的全称是Java Message Service xff0c 即Java消息服务 它主要用于在生产者和消费者之间进行消息传递 xff0c 生产者负责产生消息 xff0c 而消费者负责接收消息 把它应用到实际的业务需
  • getopt函数详解

    getopt 函数是C语言中一个常用的命令行参数解析函数 xff0c 它可以方便地解析命令行输入的参数 xff0c 以便程序对不同参数进行不同的处理 本文将详细讲解getopt 函数的使用方法和注意事项 xff0c 分点阐述如下 xff1a
  • UCOSIII

    UCOSIII简介 xff1a UCOSIII是MicroC OS III的改编版本 xff0c 主要是用于实时系统中的任务调度 xff0c 它是嵌入式系统中应用最广泛的操作系统之一 用函数说明 xff1a 1 OSInit 用于初始化UC
  • UCOSIII-任务创建-库函数

    创建任务 xff1a OSTaskCreate OS TCB amp StartTaskTCB 任务控制块 xff08 amp 传地址 xff09 CPU CHAR 34 start task 34 任务名字 xff08 可以随便写 xff
  • ucosiii-常用api

    uC OS III 提供了许多 API 函数 xff0c 可以根据需要选择使用 以下是一些常用的 uC OS III API 函数 xff1a 任务管理 API OSTaskCreate xff1a 创建一个新任务 xff1b OSTask
  • windows 清除 .git 文件夹

    有时我们需要将 git 管理项目中的 git文件夹删除 xff0c 但是如果项目太多 xff0c 一个一个手动删除太麻烦 xff0c 这时候可以用 bat 批处理文件删除 xff0c 具体操作如下 桌面 右击 新建文本文档 xff0c 此时
  • Your anti-virus program might be impacting your build performance.解决方案

    Your anti virus program might be impacting your build performance 解决方案 在使用 AndroidStudio 时 xff0c 经常会弹出框提示 xff1a Your ant
  • init.rc 启动 shell 脚本 开机执行脚本 init.rc执行shell脚本

    Android 重启时执行 shell 脚本 init rc 执行 shell 脚本 最近有个需求 xff0c 需要生成系统的默认配置 xff0c 使得在系统开机后 xff0c 直接读取已经配置好的文件 当时想的解决方案是 xff0c 在编
  • android 10 自定义系统服务接口给app调用

    Android 安卓自定义系统服务 最近有个需求 xff0c 要增加系统服务 xff0c 生成第三方 jar 包提供给第三方应用调用 xff0c 而且 jar 包必须用特定的包名 xff0c 最后生成的 jar 包不能包含 framewor
  • Android java.lang.NoSuchMethodError: No virtual method ;or its super classes (declaration of

    修改 AOSP 源码后调用错误 java lang NoSuchMethodError No virtual method in class or its super classes declaration of appears in sy
  • 谷歌使用技巧 20 招

    第一招 xff1a 使用搜索栏下方的 Tab 栏 xff0c 可以快速搜索 视频 图片 新闻第二招 xff1a 使用引号 xff0c 默认搜索会去搜索包含输入关键字的结果 xff0c 用 34 holy shit 34 会去进行整句搜索第三
  • 索引算法原理解析(B-tree以及磁盘存储原理)

    刚开始学习的时候 xff0c 百度去查 xff0c 但发现好多说得太复杂不好理解 xff0c 结合各个文章总结一下 xff08 建议大概看文字 xff0c 不理解不要紧 xff0c 然后再看图的执行步骤然后在结合文字 xff0c 这样一切就
  • C语言-----结构体内存对齐

    结构体内存对齐规则 xff1a 第一个成员在结构体变量偏移量为0 的地址处 其他成员变量要对齐到某个数字 xff08 对齐数 xff09 的整数倍的地址处 对齐数 61 编译器默认的一个对齐数与该成员大小中的较小值 vs中默认值是8 Lin