C语言——柔性数组

柔性数组概念:

这个概念你可能没听说过,但是这个概念确实存在,在C99中,结构体中最后一个成员允许是未知大小的数组,这就叫做【柔性数组】成员。

struct S
{char c;int i;int arr[0];//未知大小的数组 - 柔性数组成员
};

有些编译器可能不支持上面的写法,可以改成:

struct S
{char c;//1//3int i;//4int arr[];//未知大小的数组 - 柔性数组成员
};

柔性数组的特点:

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

我们还是以刚刚上面的结构体为例:

根据内存对齐规则,这个结构如果不算柔性数组大小的话,的确是8,而我们可以看到,这里打印出来的也确实是8,所以我们可以理解第二条特点sizeof返回结构大小的时候不包括柔性数组的大小。

那么第一条特点也就可以解释了,倘若结构里面只有柔性数组的话,那么sizeof计算结构体大小,就没办法算了,所以结构里柔性数组的前面必须至少有一个其他类型的成员。

那么第三条特点的意思是,我们在为其开辟内存的时候是这样的:

我们定义一个结构变量指针用来接收,然后malloc出来的空间首先sizeof(struct S)代表先给char和int两个成员变量开辟空间,然后剩下的+20就是给柔性数组来开辟的,内存申请的不够了,就可以用realloc重新调整大小。

具体的代码实现是这样的:

struct S
{char c;//1//3int i;//4int arr[];//未知大小的数组 - 柔性数组成员
};int main(){struct S* ps = (struct S*)malloc(sizeof(struct S) + 20);if (ps == NULL){perror("malloc");return 1;}ps->c = 'w';ps->i = 100;int i = 0;for (i = 0; i < 5; i++){ps->arr[i] = i;}//打印for (i = 0; i < 5; i++){printf("%d ", ps->arr[i]);}//空间不够了struct S* ptr = (struct S*)realloc(ps, sizeof(struct S)+40);if (ptr != NULL){ps = ptr;}else{perror("realloc");return 1;}//增容成功后,继续使用//释放free(ps);ps = NULL;return 0;
}

上面的例子就是对结构里有柔性数组的该如何进行调整,malloc以及realloc,还有即使打印使用的时候。

但是如果我们在柔性数组那里换成指针是不是也一样可以达到空间的可大可小的效果呢?

例如这样的代码:

struct s
{char c;int i;int* data;
};int main()
{struct s* ps = (struct s*)malloc(sizeof(struct s));if (ps == NULL){perror("malloc1");return 1;}ps->c = 'w';ps->i = 100;ps->data = (int*)malloc(20);if (ps->data == NULL){perror("malloc2");return 1;}int i = 0;for (i = 0; i < 5; i++){ps->data[i] = i;}for (i = 0; i < 5; i++){printf("%d ", ps->data[i]);}//空间不够了,增容int* ptr = (int*)realloc(ps->data, 40);if (ptr == NULL){perror("realloc");return 1;}else{ps->data = ptr;}/*增容成功就使用...释放*/free(ps->data);ps->data = NULL;free(ps);ps = NULL;return 0;
}

我们这里结构里放了一个指针变量成员int* data,而我们再用malloc函数申请空间并让data指向这个空间也就达到了和柔性数组一样的效果。只不过我们这里需要malloc两次:

当然也需要释放两次:

那么既然这两个代码实现的效果一样,那么哪个更好一点呢?🤔🤔🤔

答案是:第一个会更好一点。(带有柔性数组)

好处1:方便内存释放

第一个只用申请一次,而第二个则需要申请两次。

好处2:有利于访问速度

一次申请空间,空间内存一定是连续的,但是两次申请空间的话,就不一定是连续的了,内存之间就有可能存在缝隙,那么这些缝隙,也就有可能影响访问速度。(但我个人觉得其实也没多高)。

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

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

相关文章

【Docker进阶】镜像制作-用Dockerfile制作镜像(一)

进阶一 docker镜像制作 文章目录 进阶一 docker镜像制作用dockerfile制作镜像dockerfile是什么dockerfile格式为什么需要dockerfileDockerfile指令集合FROMMAINTAINERLABELCOPYENVWORKDIR 用dockerfile制作镜像 用快照制作镜像的缺陷&#xff1a; 黑盒不可重复臃肿 docker…

【日常聊聊】开源软件影响力

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 方向一&#xff1a;开源软件如何推动技术创新 方向二&#xff1a;开源软件的商业模式 方向三&#xff1a;开源软件的安全风险 方…

基于EdgeWorkers的边缘应用如何进行单元测试?

随着各行各业数字化转型的持续深入&#xff0c;越来越多企业开始选择将一些应用程序放在距离最终用户更近的边缘位置来运行&#xff0c;借此降低延迟&#xff0c;提高应用程序响应速度&#xff0c;打造更出色的用户体验。 相比传统集中部署和运行的方式&#xff0c;这种边缘应…

[office] Excel2007在工作簿中创建区域名称 #职场发展#经验分享

Excel2007在工作簿中创建区域名称 Excel 提供了几种不同的方法来创建区域名称。但在开始之前&#xff0c;必须注意关于可接受内容的重要规则: 名称不能含有空格。可以用一个下划线字符来代替空格(如Annual Total ) 。 可以使用字母和数字的任意组合&#xff0c;但是名称必须以…

3 编辑器(Vim)

1.完成 vimtutor。备注&#xff1a;它在一个 80x24&#xff08;80 列&#xff0c;24 行&#xff09; 终端窗口看起来效果最好。 2.下载我们提供的 vimrc&#xff0c;然后把它保存到 ~/.vimrc。 通读这个注释详细的文件 &#xff08;用 Vim!&#xff09;&#xff0c; 然后观察 …

CDH6.3.2 多 Spark 版本共存

一 部署Spark客户端 1.1 部署spark3客户端 tar -zxvf spark-3.3.1-bin-3.0.0-cdh6.3.2.tgz -C /opt/cloudera/parcels/CDH/lib cd /opt/cloudera/parcels/CDH/lib mv spark-3.3.1-bin-3.0.0-cdh6.3.2/ spark3将 CDH 集群的 spark-env.sh 复制到 /opt/cloudera/parcels/CDH/li…

Framework - ActivityThread 应用启动UI渲染流程

一、概念 ActivityThread拥有 main(String[] agrs) 方法&#xff0c;作为程序的入口&#xff0c;是应用程序的初始化类。&#xff08;ActivityThread不是主线程&#xff0c;它在 main() 方法中实例化&#xff0c;是运行在主线程中。&#xff09;ApplicationThread是 ActivityT…

Linux---信号

前言 到饭点了&#xff0c;我点了一份外卖&#xff0c;然后又开了一把网游&#xff0c;这个时候&#xff0c;我在打游戏的过程中&#xff0c;我始终记得外卖小哥会随时给我打电话&#xff0c;通知我我去取外卖&#xff0c;这个时候游戏还没有结束。我在打游戏的过程中需要把外…

Cannot resolve plugin org.apache.maven.plugins:maven-compiler-plugin:3.8.1

目录 【问题描述】maven环境报错 Cannot resolve plugin org.apache.maven.plugins:maven-compiler-plugin:3.8.1 【解决办法】 检查maven路径是否一致 路径一致的话&#xff0c;更改配置文件settings.xml的镜像源。 添加代码到 <mirrors> <!-- 阿里镜像 --> &l…

网络原理-TCP/IP(5)

TCP协议 延迟应答 它也是基于滑动窗口,提高效率的一种机制,结合滑动窗口以及流量控制,能够以延迟应答ACK的方式,把反馈的窗口,搞大.核心在于允许范围内,让窗口尽可能大. 如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小. 1.假设接收端缓冲区为1M.一次收到了5…

新手小白零基础一分钟自动部署搭建幻兽帕鲁服务器教程

对于初次接触游戏联机服务器搭建的新手玩家来说&#xff0c;部署和配置一个像“幻兽帕鲁”这样的网络游戏联机服务器可能会显得有些复杂。但别担心&#xff0c;本文将提供一种快速、简洁且适合零基础新手的一分钟自动部署搭建幻兽帕鲁游戏联机服务器的详细教程。 本文将为大家提…

Linux 驱动开发基础知识——内核对设备树的处理与使用(十)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;Vir2021GKBS &#x1f43c;本文由…

Oracle闪回日志管理(flashbackup log)

Oracle闪回日志管理&#xff08;flashbackup log&#xff09; 1.开启闪回日志 shutdown immediate startup mount; alter database archivelog; alter database flashback on; alter database open; 2、查看闪回日志保留期限 show parameter flash 默认是1440分钟&#xff0c…

【LeetCode】刷题总结 - 15. 三数之和

15. 三数之和 | LeetCode 思路 首先对 nums 进行排序&#xff0c;然后设置三个指针&#xff1a;left、mid、right&#xff1a; left 从最左边开始&#xff0c;依次向后遍历每次固定住 left 后&#xff0c;就化为一个 2sum 问题&#xff1a; mid left 1&#xff0c;right …

python中[[]] * (n)和[[] for _ in range(n)]的区别

1、现象 刷leetcode207的时候碰到一个坑&#xff0c;用[[]] * (n)初始化二维数组&#xff0c;逻辑是正确的&#xff0c;但是结果始终不对。 2、原因 最后定位是初始化语句使用错误导致的&#xff0c;我使用的是[[]] * (n)&#xff0c;应该使用[[] for _ in range(n)] 3、解…

SpringBoot:实例一

一、实现的效果 在浏览器地址栏输入http://localhost:8080/hello&#xff0c;当前页面显示hello world 实例一代码&#xff1a;点击查看LearnSpringBoot01 点击查看更多的SpringBoot教程 二、 效果图 三、 pom.xml代码 <?xml version"1.0" encoding"UTF-…

【快速上手QT】01-QWidgetQMainWindow QT中的窗口

总所周知&#xff0c;QT是一个跨平台的C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序&#xff0c;当然我们用到QT就是要做GUI的&#xff0c;所以我们快速上手QT的第一篇博文就讲QT的界面窗口。 我用的IDE是VS2019&#xff0c;使用QTc…

【小白学unity记录】使用unity播放声音

1. 示例 unity中播放声音涉及到两个组件。AudioSource和AudioClip。AudioSource可以理解为播放器&#xff0c;AudioClip可以理解为音频片段文件。AudioSource可以通过.clip属性切换音频片段。 using UnityEngine;public class PlayerController : MonoBehaviour {private int…

Windows11通过Hyper-V创建VM,然后通过vscode连接vm进行开发

这边需要在win11上建立vm来部署docker(这边不能用windows版本的docker destop)&#xff0c;学习了下&#xff0c;记录。 下载系统镜像 首先下载系统镜像&#xff1a;https://releases.ubuntu.com/focal/ 这边使用的是ubuntu20.04.6 LTS (Focal Fossa) &#xff0c;Server inst…

Facebook的数字合作愿景:创新与未来发展

随着科技的飞速发展&#xff0c;Facebook一直处于数字创新的前沿&#xff0c;致力于构建开放、智能、社交的数字社交体验。本文将深入探讨Facebook的数字合作愿景&#xff0c;探索其在创新与未来发展方面的雄心壮志。 引言 在当今数字化时代&#xff0c;社交媒体不仅是人们沟通…