【C】柔性数组

news2024/9/26 1:16:13

柔性数组

也许你从来没有听说过柔性数组flexible array)这个概念,但是它确实是存在的。

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

例如:

在这里插入图片描述

柔性数组的特点

  • 结构中的柔性数组成员前面必须至少有一个其他成员。

  • sizeof 返回的这种结构大小不包括柔性数组的内存。

  • 包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

柔性数组前需要有至少应该成员:

为带有柔性数组成员的结构体开辟的空间必须比结构体的最小的占用内存大小更大:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

当空间不够使用,需要增容的时候,我们可以用realloc进行增容

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在数组可通过malloc开辟,也可通过realloc增容,具备了可扩展性,体现了柔性,因此称为柔性数组。

结构体最后应该数组元素大小需要是可变化的可扩展的时候,就需要用到柔性数组了。(应用少,并不流行)

代码1

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

int main()
{
	//printf("%d\n", sizeof(struct S));//输出4
	struct S* ps = malloc(sizeof(struct S) + 40);
	if (ps == NULL)
	{
		perror("malloc");
		return 0;
	}
	ps->n = 100;
	int i = 0;
	for (i = 0; i < 10; i++)//逐个元素赋值
	{
		ps->arr[i] = i + 1;
	}
	//空间不够,需要增容
	struct S* ptr = realloc(ps, sizeof(struct S) + 60);
	if (ptr == NULL)//增容失败
	{
		perror("realloc");
		return 1;
	}
	ps = ptr;//增容成功
	ps->n = 15;
	for (i = 0; i < 15; i++)
	{
		printf("%d\n", ps->arr[i]);//打印柔性数组前15个
	}
	//释放空间
	free(ps);
	ps = NULL;
	return 0;
}

其他方法实现柔性数组

有没有一种方案可以替代柔性数组呢,用其他方法来实现一模一样的效果。

先开辟出结构体大小的空间,然后用arr作为起始地址开辟一段新的空间存放数组,这段数组可以用realloc增容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

代码2

//柔性数组的替换
struct S
{
	int n;
	int* arr;
};
int main()
{
	
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	if (ps == NULL)
	{
		perror("malloc->ps");
		return 1;
	}
		
	ps->n = 100;
	ps->arr = (int*)malloc(40);
	if (ps->arr == NULL)
	{
		perror("malloc->arr");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = i + 1;
	}
	//调整增容
	int* ptr = (int*)realloc(ps->arr, 60);
	if (ptr != NULL)
	{
		ps->arr = ptr;
	}
	else
	{
		perror("realloc");
		return 1;
	}
	//打印
	for (i = 0; i < 15; i++)
	{
		printf("%d\n", ps->arr[i]);
	}
	//释放
	free(ps->arr);
	ps->arr = NULL;

	free(ps);
	ps = NULL;
	return 0;
}

柔性数组的优势

上述 代码1 和 代码2 可以完成同样的功能,但是 方法1 的实现有两个好处

第一个好处是:方便内存释放。

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

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

连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tab切换样式

一、样式一 <view class"tabs"><view class"tab" :class"{active: active index}" v-for"(item, index) in tabs" click"active index">{{item.label}}</view></view> data(){return {active: 0…

Codeforces Round 905 (Div. 3)

目录 A. Morning B. Chemistry C. Raspberries D. In Love E. Look Back F. You Are So Beautiful G1. Dances (Easy version) G2. Dances (Hard Version) A. Morning time limit per test 2 seconds memory limit per test 256 megabytes input standard input …

重磅新闻-国内首家八类网线认证分析仪上市了

伴随USA对国内某些敏感企业的非常不友好&#xff0c;设置层层障碍&#xff0c;技术堡垒。使得一些网线基础制造研发、线缆线束厂、汽车生产生产厂、军工用途的线缆品质的认证、以及相关高校的研发受到了不同的程度的阻碍。重磅消息&#xff0c;国内首家八类网线认证测仪-维信仪…

Vue前后端分离的低代码开发框架

目录 项目简介 平台特性 1.构架特性 2.功能特性 技术栈 1.后端技术栈 2.前端技术栈 2.1 Vue2技术栈 2.2 Vue3技术栈 3.数据库支持 部署方式 项目简介 JNPF开发平台是一个基于SpringBootVue3的全栈开发平台&#xff0c;采用微服务、前后端分离架构。前后端封装了上千…

【多线程相关其一】Python并发编程

1.为什么要引入并发编程 场景1&#xff1a;一个网络爬虫&#xff0c;按顺序爬取花了1个小时&#xff0c;采用并发下载减少到20分钟。 场景2&#xff1a;一个APP应用&#xff0c;优化前每次打开页面需要3秒&#xff0c;采用异步并发提升到每次200毫秒 引入并发&#xff0c;就是…

Centos系统安装阿里云盘+简单使用

GitHub地址&#xff1a; 1、安装阿里云盘 wget https://github.com/tickstep/aliyunpan/releases/download/v0.2.7/aliyunpan-v0.2.7-linux-amd64.zip unzip aliyunpan-v0.2.7-linux-amd64.zip mv aliyunpan-v0.2.7-linux-amd64 /usr/local/aliyunpan ln -s /usr/local/aliyu…

安装Jdk 报错 ,Java SE Development Kit 8 Update 202(64-bit)安装完毕之前,向导被中断

具体原因没有找到&#xff0c;估计是由于jdk 没有删干净导致的&#xff0c;我的处理方法是&#xff0c;将 Java的注册表全然后手动安装 Jdk和导入注册表&#xff08;在同事那里获取jdk文件 压缩包&#xff0c;并将 java的注册表导出&#xff0c;放在自己电脑上使用。&#xff0…

动手学深度学习——第七次学

LeNet&#xff08;LeNet-5&#xff09;由两个部分组成&#xff1a; 卷积编码器和全连接层密集块 卷积把高宽不断变小&#xff0c;把通道数逐渐增多&#xff0c;&#xff08;最后高宽会变成&#xff0c;通道会变得很大&#xff0c;然后做全连接进行输出&#xff09;通道信息可以…

Leetcode—1488.避免洪水泛滥【中等】

2023每日刷题&#xff08;十四&#xff09; Leetcode—1488.避免洪水泛滥 算法思想 将晴天的日期全部记录在set<int> sun中使用unordered_map<int, int> lakeRainy来记录每个湖泊上一次下雨的日期遇到晴天时先不用管抽哪个湖当下雨时&#xff0c;湖泊已经装满水时…

QT5 通过 webview2 加载网页

官方文档参考&#xff1a;https://learn.microsoft.com/zh-cn/microsoft-edge/webview2/get-started/win32 Webview2依赖的头文件和库 头文件主要为&#xff1a;WebView2和WixLibrary&#xff0c;存储在include/external 库主要为&#xff1a;WebView2LoaderStatic.lib和W…

C++——类和对象(构造函数与析构函数)

构造函数与析构函数 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的Xmind文件和.png文件都已导入到”资料“中 1. 构造函数 以前&#xff0c;我们写一个Date类一般是这么写的&#xff1a; class Date { public :void Init(int year, int month, int day){_year…

Unity Animator cpu性能测试

测试案例&#xff1a; 场景中共有4000个物体&#xff0c;挂在40个animtor 上&#xff0c;每个Animator控制100个物体的动画。 使用工具&#xff1a; Unity Profiler. Unity 版本&#xff1a; unity 2019.4.40f1 测试环境&#xff1a; 手机 测试过程&#xff1a; 没有挂…

解读电力系统中的GPS北斗卫星同步时钟系统

随着电力系统的快速发展,变电站中的各类系统 &#xff1a;计算机监控系统、水情测报系统、视频监控系统 状态监测系统 生产信息管理系统等&#xff0c;各类装置&#xff1a;继电保护装置、故障录波装置、PMU装置、事件顺序记录SOE功能越来越强大&#xff0c;需要采集、记录的数…

CSS3背景样式

在CSS 2.1中&#xff0c;background属性的功能还无法满足设计的需求&#xff0c;为了方便设计师更灵活地设计需要的网页效果&#xff0c;CSS3在原有background基础上新增了一些功能属性&#xff0c;可以在同一个对象内叠加多个背景图像&#xff0c;可以改变背景图像的大小尺寸&…

LeetCode热题100 48.旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9…

2022年09月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 运行以下代码&#xff0c;结果输出的是&#xff1f;&#xff08; &#xff09; means[Thank,You] print(len(means))A…

Android开发知识学习——TCP / IP 协议族

文章目录 学习资源来自&#xff1a;扔物线TCP / IP 协议族TCP连接TCP 连接的建立与关闭TCP 连接的建立为什么要三次握手&#xff1f; TCP 连接的关闭为什么要四次挥手&#xff1f; 为什么要⻓连接&#xff1f; 常见面试题课后题 学习资源来自&#xff1a;扔物线 TCP / IP 协议…

潜力无限!深眸科技以工业视觉软硬件一体化解决方案深入应用场景

工业视觉作为智能制造的眼睛&#xff0c;在制造业各场景中具有广泛的应用前景&#xff0c;尤其是在检测、引导、定位、测量等方面应用需求不断提高。深眸科技为进一步巩固和加强技术领先优势&#xff0c;持续拓宽机器视觉技术的应用边界&#xff0c;通过先进的硬件设备和自研的…

86 最小栈

最小栈 题解1 STL大法好题解2 辅助最小栈&#xff08;直观&#xff0c;空间换时间&#xff09;题解3 不需要额外空间(!!!差值!!!) 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…