C语言学习

柔性数组
友情链接:C语言专栏


文章目录

  • C语言学习
  • 前言:
  • 柔性数组
  • 一、柔性数组的特点
  • 二、柔性数组的使用
  • 三、柔性数组的优势
  • 总结
  • 附录
    • 上文链接
    • 专栏


前言:

在有结构体和动态内存分配的知识后,今天咱们来说说柔性数组吧!!!


柔性数组

C99 中,结构中的最后⼀个元素允许是未知大小的数组,这就叫做柔性数组成员。
例如:

struct S
{int i;int a[0];//柔性数组成员
};

有些编译器会报错⽆法编译可以改成:

struct S
{int i;int a[];//柔性数组成员
};

一、柔性数组的特点

  1. 结构中的柔性数组成员前面必须至少一个其他成员。
  2. sizeof 返回的这种结构大小不包括柔性数组的内存。
  3. 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

示例:

struct S
{int i;int a[];//柔性数组成员
};
int main()
{printf("%d\n", sizeof(struct S));//输出的是4return 0;
}

输出:
在这里插入图片描述

二、柔性数组的使用

//代码1
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int a[];//柔性数组成员
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));//动态开辟内存:4+20个字节//4个字节为i,20个字节为数组if (ps == NULL)//判断是否开辟成功{perror("malloc failed");exit(EXIT_FAILURE);  }//使用:ps->i = 100;for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空间reallocstruct S* tmp = (struct S*)realloc(ps, sizeof(struct S) + 10 * sizeof(int)); //给数组增加20个字节(5个元素)if (tmp == NULL)//判断是否开辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps = tmp;//继续由ps管理这块内存;tmp = NULL;//使用//……//释放free(ps);ps = NULL;return 0;
}

三、柔性数组的优势

上述的结构也可以设计为别的结构,也能完成同样的效果。

//代码2
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int* a;//通过指针指向一块空间,实现与柔性数组相同的效果
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));//动态开辟内存一个struct S大小的空间if (ps == NULL)//判断是否开辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->i = 100;ps->a = (int*)malloc(5 * sizeof(int)); //动态开辟内存5个int大小的空间,并将起始地址给aif (ps->a == NULL)//判断是否开辟成功{perror("malloc failed");exit(EXIT_FAILURE);}//使用for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空间reallocint* tmp = (int*)realloc(ps->a, sizeof(10 * sizeof(int)));//给ps->a指向的空间增加20个字节(5个元素)if (tmp == NULL)//判断是否开辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->a  = tmp;tmp = NULL;//使用//……//释放//注意先后顺序free(ps->a );ps->a  = NULL;free(ps);ps = NULL;return 0;
}

上述代码1和代码2可以完成同样的功能,但是代码1的实现有两个好处:
第一个好处是:方便内存释放

咱们上面发现,代码2我们会释放两次内存。有如果我们的代码是在⼀个给别⼈用的函数中,你在里面做了二次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给用户⼀个结构体指针,用户做⼀次free就可以把所有的内存也给释放掉。

第二个好处是:这样有利于访问速度

连续的内存有益于提高访问速度,也有益于减少内存碎片。图示:
在这里插入图片描述


总结

柔性数组是C99标准引入的重要特性,它允许在结构体的末尾定义一个长度可变的数组。通过结合动态内存管理,柔性数组能够高效地处理不确定大小的数据集合,是C程序员进阶必备技能之一。

附录

上文链接

《动态内存分配避坑指南:六大易错点解析与经典笔试题实战》

专栏

C语言专栏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/914992.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/914992.shtml
英文地址,请注明出处:http://en.pswp.cn/news/914992.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RV126平台NFS网络启动终极复盘报告

1. 初始目标与环境目标: 将RV1126开发板的启动方式&#xff0c;由从eMMC内部存储挂载根文件系统&#xff08;rootfs&#xff09;&#xff0c;切换为通过网络挂载位于NFS服务器上的根文件系统。动机: 提升开发调试效率&#xff0c;实现代码修改后仅需重启即可验证&#xff0c;免…

一台显示器上如何快速切换两台电脑主机?

我注意到很多人会遇到一个常见的情况&#xff1a;他们有两台电脑&#xff0c;一台旧的用来处理基本的办公任务&#xff0c;另一台新的用来玩游戏。新手通常会用 DP端口连接第一台电脑的显示器&#xff0c;用 HDMI 连接第二台电脑。当他们想在两台电脑之间切换时&#xff0c;经常…

抗辐照与国产替代:ASM1042在卫星光纤放大器(EDFA)中的应用探索

摘要&#xff1a;本文以国科安芯推出的ASM1042芯片为例&#xff0c;通过分析ASM1042的抗辐照性能、高速数据传输能力、可靠性以及国产化优势&#xff0c;结合EDFA系统的需求特点&#xff0c;深入探讨了其在商业卫星光纤放大器&#xff08;EDFA&#xff09;项目中的应用潜力。AS…

鸿蒙ArkUI:声明式开发,高效构建全场景体验

目录 导言&#xff1a;开启鸿蒙应用开发的新范式 ArkUI框架概览 - 鸿蒙UI的灵魂 深入核心 - 声明式UI开发范式 命令式 vs 声明式&#xff1a;范式革命 ArkUI如何实现声明式&#xff1f; 创建内置组件 创建自定义组件 自定义组件的基本结构 ArkUI框架的核心特性与优势 …

数据查找 二叉查找树

查找一般分为有序查找和无序查找&#xff0c;这边在讲有序查找例二分查找二分查找就是在有序数组中&#xff0c;通过mid(lowhigh)/2来判定中间值&#xff0c;将中间值与待查找的值进行比较&#xff0c;如果待查找的值大于中间值&#xff0c;那么就将范围缩小&#xff0c;查找右…

几款开源的安全监控与防御工具分享

安全监控与防御工具概述 在现代网络安全架构中,合理选择和部署一系列的安全监控、检测、响应工具至关重要。下面我们将介绍一些常见的安全工具,包括 Elkeid、Wazuh、Caldera、ELK、Snort、Suricata、OpenHFW、OSSEC、GScan 和 Sysom,并详细介绍它们的下载链接、用处、使用方…

Elasticsearch:ES|QL 改进的时间线

作者&#xff1a;来自 Elastic Toms Mura 让我们回顾一下 ES|QL 的历史和它的改进。 更多阅读&#xff0c;Elasticsearch&#xff1a;ES|QL 查询展示。 Elasticsearch 配备了众多新功能&#xff0c;帮助你为自己的用例构建最佳搜索方案。查看我们的示例笔记本了解更多内容&…

Linux | Bash 子字符串提取

注&#xff1a;本文为 “ Bash 子字符串提取” 相关合辑。 英文引文&#xff0c;机翻未校。 如有内容异常&#xff0c;请看原文。 How to Extract Bash Substring? [5 methods] 如何提取 Bash 子字符串&#xff1f;[5 种方法] 2024-04-28 00:00:00 In Bash, a substring is…

Vue2 前端开发 - vue-quill-editor 富文本编辑器(编辑器基础案例、编辑器配置参数解读、编辑器事件)

一、vue-quill-editor 1、vue-quill-editor 概述vue-quill-editor 是一个基于 Quill 富文本编辑器的 Vue 组件vue-quill-editor 在 Vue 2 项目中可以很方便地集成与使用2、vue-quill-editor 安装 执行如下指令&#xff0c;安装 vue-quill-editor npm install vue-quill-editor …

断网情况下,网线直连 Windows 笔记本 和Ubuntu 服务器

在断网情况下&#xff0c;通过网线直连 Windows 笔记本 和 Ubuntu 服务器&#xff0c;并使用 VSCode 访问服务器及 Docker 容器 的步骤如下&#xff1a;1. 物理连接&#xff08;网线直连&#xff09; 1.1 使用网线连接 用 网线&#xff08;Cat5e 或更高&#xff09; 连接 Windo…

消息队列总结

为什么需要消息队列&#xff1f; 随着互联网快速发展&#xff0c;业务规模不断扩张&#xff0c;技术架构从单体演进到微服务&#xff0c;服务间调用复杂、流量激增。为了解耦服务、合理利用资源、缓冲流量高峰&#xff0c;「消息队列」应运而生&#xff0c;常用于异步处理、服务…

C#引用转换核心原理:类型视角切换

&#x1f50d; C#引用转换核心原理&#xff1a;类型视角切换 引用类型由内存指针和类型标记组成&#xff08;如图1&#xff09;。引用转换不改变内存地址&#xff0c;仅改变编译器识别对象的“视角”&#xff1a; B myVar1 new B(); // 实际B类型对象 A myVar2 (A)myV…

重要发布丨MaxKB V2正式发布,助力用户快速构建企业级智能体

2025年7月18日&#xff0c;MaxKB V2版本正式发布。MaxKB是一个强大易用的企业级智能体平台&#xff0c;致力于解决企业AI落地所面临的技术门槛高、部署成本高、迭代周期长等问题&#xff0c;让企业用户落地AI更简单。 秉承“开箱即用&#xff0c;伴随成长”的设计理念&#xff…

大语言模型任务分解与汇总:从认知瓶颈到系统化解决方案

一、缘起&#xff1a;为什么大模型需要"分而治之" 1.1 从一个真实场景说起 设想这样一个场景&#xff1a;你要求GPT-4帮你完成一份包含市场调研、竞品分析、财务预测和战略规划的商业计划书。即使是最先进的大模型&#xff0c;面对这样的复杂任务也会"力不从心&…

Spring核心注解@RequestMapping详解

RequestMapping 是 Spring Framework 中一个核心注解&#xff0c;用于在 Spring MVC&#xff08;或 Spring WebFlux&#xff09;中将 HTTP 请求映射到特定的处理器&#xff08;Controller 中的方法&#xff09;或处理器类。它告诉 Spring 框架&#xff1a;当一个匹配特定条件的…

OSPF路由协议的协商过程

OSPF的知识点非常多&#xff0c;协议过程也是一个不大不小的知识点&#xff0c;今天就简单的说一下&#xff0c;OSPF是如何进行协商的。OSPF&#xff08;Open Shortest Path First&#xff09;协议是一种用于路由选择的动态链路状态协议&#xff0c;是大型网络普遍使用的动态路…

MySql:索引,结构

文章目录注意事项结构注意事项 主键字段在建表时&#xff0c;会自动创建主键索引添加唯一约束时&#xff0c;数据库实际上会添加唯一索引。 解释&#xff1a; 增&#xff1a;创建&#xff1a; create [unique] index 索引名 on 表名 (字段名……)&#xff1b;-- 举例 :给tb…

ts学习2

JavaScript 中的每个值都有一组行为&#xff0c;您可以通过运行不同的操作来观察这些行为。这听起来很抽象&#xff0c;但作为一个简单的例子&#xff0c;考虑我们可能在名为 message 的变量上运行的一些操作。 // Accessing the property toLowerCase // on message and then…

k8s环境使用Operator部署Seaweedfs集群(下)

作者&#xff1a;闫乾苓 文章目录4.4.3 部署seaweedfs集群4.4.4 验证集群运行状态4.4.5 测试集群功能4.4.3 部署seaweedfs集群 集群Yaml示例 apiVersion: seaweed.seaweedfs.com/v1 kind: Seaweed metadata:name: seaweed1namespace: default spec:image: chrislusf/seaweedf…

【橘子分布式】gRPC(理论篇)

一、简介 我们在前面学习了thrift rpc的知识&#xff0c;我们从其中接触到了IDL&#xff0c;编解码协议&#xff0c;服务的远程调用(调用远程服务就像在在本地调用一样)等各种概念。 其实我个人对thrift的使用并不多&#xff0c;我更多的是使用今天我们要提到的一个RPC框架称之…