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

深入解析 C 语言中含数组和指针的构造体与共同体内存计算

        在 C 语言中,构造体(struct)和共同体(union)允许我们将多种数据类型组合到一起。除了常见的基本数据类型之外,经常还会在它们中嵌入数组和指针。由于数组的内存是连续分配的,而指针的大小与平台相关(32 位一般为 4 字节,64 位一般为 8 字节),计算内存大小时就需要特别注意内存对齐填充的影响。本文将通过具体示例说明如何计算包含数组和指针的构造体和共同体的内存大小。

 一、构造体(Struct)中包含数组和指针

1.1基本原理

  • 数组:数组内存占用空间为“数组元素个数×单个元素大小”,且所有元素是连续排列。
  • 指针:指针只存储一个地址,其大小固定(取决编译平台,与指向数据无关)。
  • 内存对齐与填充:编译器为了提高内存访问效率,会按照每个成员的对齐要求进行排列。如果某个成员的起始地址不满足对齐要求,编译器会在前面插入填充字节。同时整个结构体的大小也会被调整为结构体中最大对齐要求的整倍数。

1.2示例: 构造体包含数组和指针

        假设在 64 位系统下(指针大小为 8 字节,int 为 4 字节,char 为 1 字节),如下构造体的定义为例:

struct Example {char a;        // 1 字节int b;         // 4 字节,要求 4 字节对齐char arr[3];   // 数组,占 3 字节int *ptr;      // 指针,占 8 字节(64 位系统)
};

内存布局分析

1.成员 a(char):

  • 从偏移 0 开始,占 1 字节。

2.成员 b(int):

  • 由于 int 要求 4 字节对齐,而 a 只占 1 字节,所以在 a 后面需要 3 字节填充,使得 b 的起始地址为偏移 4。
  • b 占 4 字节,从偏移 4 到 7。

3.成员 arr[3](数组):

  • 紧接在 b 后面,从偏移 8 开始。
  • 数组大小为 3 字节,覆盖偏移 8、9、10。

4.成员 ptr(指针):

  • 指针要求 8 字节对齐,而当前下一个可用偏移为 11,不满足 8 字节对齐(因为 11 不是 8 的倍数)。
  • 编译器需要在 arr 后插入 5 字节填充,使得 ptr 从偏移 16 开始。
  • ptr 占 8 字节,从偏移 16 到 23。

5.整体大小调整:

  • 当前各部分占用总字节数为 24 字节(0~23),而最大对齐要求为 8 字节,24 已经是 8 的倍数,因此最终结构体大小为 24 字节

1.3 嵌套构造体中包含数组和指针

        假设在 64 位系统下(指针大小为 8 字节,int 为 4 字节,char 为 1 字节),如下构造体的定义为例:

struct Example {char a;        // 1 字节int b;         // 4 字节,要求 4 字节对齐char arr[3];   // 数组,占 3 字节int *ptr;      // 指针,占 8 字节(64 位系统)
};
内存布局分析

1.成员 a(char):

  • 从偏移 0 开始,占 1 字节。

2.成员 b(int):

  • 由于 int 要求 4 字节对齐,而 a 只占 1 字节,所以在 a 后面需要 3 字节填充,使得 b 的起始地址为偏移 4。
  • b 占 4 字节,从偏移 4 到 7。

3.成员 arr[3](数组):

  • 紧接在 b 后面,从偏移 8 开始。
  • 数组大小为 3 字节,覆盖偏移 8、9、10。

4.成员 ptr(指针):

  • 指针要求 8 字节对齐,而当前下一个可用偏移为 11,不满足 8 字节对齐(因为 11 不是 8 的倍数)。
  • 编译器需要在 arr 后插入 5 字节填充,使得 ptr 从偏移 16 开始。
  • ptr 占 8 字节,从偏移 16 到 23。

5.整体大小调整:

  • 当前各部分占用总字节数为 24 字节(0~23),而最大对齐要求为 8 字节,24 已经是 8 的倍数,因此最终结构体大小为 24 字节

二、共同体(union)中包含数组和指针 

2.1 基本原理

        在共同体中,所有成员共享同一块内存,其大小由最大成员的大小决定,同时也需要满足该成员的对齐要求。即使共同体中包含数组和指针,原则也是一致的。

2.2 示例:共同体中包含数组和指针

union Union {int arr[4];    // 数组:4 个 int,每个 4 字节,总共 16 字节double *dptr;  // 指针,8 字节(64 位系统)char c[10];    // 数组:10 个 char,总 10 字节
};
内存大小计算
  • arr[4] 占 4 × 4 = 16 字节
  • dptr 占 8 字节
  • c[10] 占 10 字节

取最大值: 最大成员为 arr[4],大小为 16 字节。
同时需要考虑最大对齐要求,假设 int 要求 4 字节,而指针要求 8 字节;由于最大成员(数组)的元素对齐为 4 字节,但联合体的整体对齐要求通常取决于所有成员中最大的(这里可能由指针决定为 8 字节),不过最终分配空间依旧是 16 字节(且该空间会按 8 字节对齐)。因此,该共同体的总大小为 16 字节

三、总结与注意事项

1.构造体(struct):

  • 内存分布为成员按照声明顺序排列。
  • 数组成员按照数组中所有元素总大小分配。
  • 指针成员只占指针本身大小,不考虑所指数据。
  • 必须考虑每个成员的对齐要求,必要时插入填充字节,整体大小也需调整为最大对齐要求的整数倍。
  • 嵌套构造体时,先计算内部结构体的大小,再按照外部成员的排列顺序计算整体大小。

2.共同体(union):

  • 所有成员共享同一块内存,大小取决于最大的成员(同时满足对齐要求)。
  • 数组和指针的计算方法依然适用,但只取最大值即可。

相关文章:

深入解析 C 语言中含数组和指针的构造体与共同体内存计算

在 C 语言中,构造体(struct)和共同体(union)允许我们将多种数据类型组合到一起。除了常见的基本数据类型之外,经常还会在它们中嵌入数组和指针。由于数组的内存是连续分配的,而指针的大小与平台…...

【C++模板】:开启泛型编程之门(函数模版,类模板)

📝前言: 在上一篇文章C内存管理中我们介绍了C的内存管理,重点介绍了与C语言的区别,以及new和delete。这篇文章我们将介绍C的利器——模板。 在C编程世界里,模板是一项强大的特性,它为泛型编程奠定了坚实基础…...

HEC-HMS水文建模全解析:气候变化与极端水文、离散化流域单元‌精准刻画地表径流、基流与河道演进过程‌

一、技术革新:数字流域的精密算法革命 在全球气候变化与极端水文事件频发的双重压力下,HEC-HMS模型凭借其‌半分布式建模架构‌与‌多尺度仿真能力‌,已成为现代流域管理的核心工具。该模型通过‌离散化流域单元‌精准刻画地表径流、基流与河…...

具备多种功能的PDF文件处理工具

软件介绍 在日常办公和学习场景中,PDF文件使用极为频繁,而一款功能强大的PDF编辑软件能大幅提升处理效率。 今天要介绍的Adobe Acrobat Pro DC 2024.005.20414,就具备像编辑Word文档一样便捷编辑PDF的能力。 PDF文档在学习和工作中广泛应用…...

【SpringMVC】SpringMVC的启动过程与原理分析:从源码到实战

SpringMVC的启动过程与原理分析:从源码到实战 SpringMVC是Spring框架中用于构建Web应用的核心模块,它基于MVC(Model-View-Controller)设计模式,提供了灵活且强大的Web开发能力。本文将深入分析SpringMVC的启动过程、核…...

转自南京日报:天洑软件创新AI+仿真技术变制造为“智造

以下文章来源:南京日报 进入3月,南京天洑软件有限公司(以下简称天洑软件)董事长张明更加忙碌。“公司强调工业软件在数字经济与先进制造业融合中的关键作用,并已广泛应用在能源、电力和航空等领域。”他说,…...

golang dlv调试工具

golang dlv调试工具 在goland2022.2版本 中调试go程序报错 WARNING: undefined behavior - version of Delve is too old for Go version 1.20.7 (maximum supported version 1.19) 即使你go install了新的dlv也无济于事 分析得出Goland实际使用的是 Goland安装目录下dlv 例…...

LSTM方法实践——基于LSTM的汽车销量时序建模与预测分析

Hi,大家好,我是半亩花海。本实验基于汽车销量时序数据,使用LSTM网络(长短期记忆网络)构建时间序列预测模型。通过数据预处理、模型训练与评估等完整流程,验证LSTM在短期时序预测中的有效性。 目录 一、实验…...

微服务——网关、网关登录校验、OpenFeign传递共享信息、Nacos共享配置以及热更新、动态路由

之前学习了Nacos,用于发现并注册、管理项目里所有的微服务,而OpenFeign简化微服务之间的通信,而为了使得前端可以使用微服务项目里的每一个微服务的接口,就应该将所有微服务的接口管理起来方便前端调用,所以有了网关。…...

【数据结构】二叉搜索树、平衡搜索树、红黑树

二叉搜索树(Binary Search Tree) 二叉搜索树是一种特殊的二叉树,它用来快速搜索某个值,对于每个节点都应该满足以下条件: 若该节点有左子树,那么左子树中所有节点的值都应该小于该节点的值。若该节点有右…...

Spring Boot 解析 LocalDateTime 失败?Uniapp 传输时间变 1970 的原因与解决方案

目录 前言1. 问题分析2. 时间戳(推荐,可尝试)3. 使用 JsonDeserialize & JsonSerialize(中立)4. 前端传 ISO-8601 格式(不推荐,可尝试)5. 用 String(中立&#xff09…...

Xilinx ZYNQ FSBL解读:LoadBootImage()

篇首 最近突发奇想,Xilinx 的集成开发环境已经很好了,很多必要的代码都直接生成了,这给开发者带来了巨大便利的同时,也让人错过了很多代码的精彩,可能有很多人用了很多年了,都还无法清楚的理解其中过程。博…...

mysql中in和exists的区别?

大家好,我是锋哥。今天分享关于【mysql中in和exists的区别?】面试题。希望对大家有帮助; mysql中in和exists的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MySQL 中,IN 和 EXISTS 都用于进行子查询,但它…...

oracle 数据导出方案

工作中有遇到需要将oracle 数据库表全部导出,还需要去除表数据中的换行符。 方案 shell 设计 封装函数 1 function con_oracle() 用于连接oracle 2 function send_file() 用于发送文件 3 主程序 使用循环将所有表导出并发送到数据服务器 主程序 程序代码 #!…...

Apache Commons Lang3 和 Commons Net 详解

目录 1. Apache Commons Lang3 1.1 什么是 Apache Commons Lang3? 1.2 主要功能 1.3 示例代码 2. Commons Net 2.1 什么是 Commons Net? 2.2 主要功能 2.3 示例代码 3. 总结 3.1 Apache Commons Lang3 3.2 Commons Net 3.3 使用建议 4. 参考…...

从0开始的操作系统手搓教程33:挂载我们的文件系统

目录 代码实现 添加到初始化上 上电看现象 挂载分区可能是一些朋友不理解的——实际上挂载就是将我们的文件系统封装好了的设备(硬盘啊,SD卡啊,U盘啊等等),挂到我们的默认分区路径下。这样我们就能访问到了&#xff…...

【Linux】36.简单的TCP网络程序

文章目录 1. TCP socket API 详解1.1 socket():打开一个网络通讯端口1.2 bind():绑定一个固定的网络地址和端口号1.3 listen():声明sockfd处于监听状态1.4 accept():接受连接1.5 connect():连接服务器 2. 实现一个TCP网络服务器2.1 Log.hpp - "多级日志系统"2.2 Daem…...

时序分析

1、基本概念介绍 1.1、 建立时间 T(su) 建立时间:setup time,它是指有效的边沿信号到来之前,输入端口数据保持稳定的时间。 1.1.1、 建立时间要求: 建立时间要求指的是 想要寄存器如期的工作,在有效时…...

doris:ClickHouse

Doris JDBC Catalog 支持通过标准 JDBC 接口连接 ClickHouse 数据库。本文档介绍如何配置 ClickHouse 数据库连接。 使用须知​ 要连接到 ClickHouse 数据库,您需要 ClickHouse 23.x 或更高版本 (低于此版本未经充分测试)。 ClickHouse 数据库的 JDBC 驱动程序&a…...

NLP常见任务专题介绍(1)-关系抽取(Relation Extraction, RE)任务训练模板

📌 关系抽取(Relation Extraction, RE)任务训练示例 本示例展示如何训练一个关系抽取模型,以识别两个实体之间的关系。 1️⃣ 任务描述 目标:从文本中提取两个实体之间的语义关系,例如 “人物 - 组织”、“药物 - 疾病”、“公司 - 创始人” 等。输入:句子 + 标注的实…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...