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

【C语言进阶】柔性数组

在这里插入图片描述
在这里插入图片描述

目录

  • 一:柔性数组的特点
  • 二:柔性数组的使用
  • 三:模拟实现柔性数组

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

以下是柔性数组的两种写法:

//写法一:
struct S
{
	int n;
	char c;
	char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};

//写法二:
struct S
{
	int n;
	char c;
	char arr[0];//0也说明它的大小是未知的 - - 柔性数组成员
};

一:柔性数组的特点

  • 结构体中的柔性数组成员前面必须至少一个其他成员
  • sizeof返回的这种结构体大小不包括柔性数组的大小
  • 包含柔性数组成员的结构体malloc函数进行动态内存分配,并且分配的内存应该大于结构体的大小,以适应柔性数组的预期大小。
//利用malloc进行空间分配
struct S
{
	int n;
	char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};

int main()
{
	printf("%d\n", sizeof(struct S));
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//后面的10 * sizeof(char)就是为arr数组开辟的
	return 0;
}

二:柔性数组的使用

#include <stdio.h>
#include <stdlib.h>

struct S
{
	int n;
	char arr[];//数组大小没有写说明它的大小是未知的 - - 柔性数组成员
};

int main()
{
	printf("%d\n", sizeof(struct S));
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));//后面的10 * sizeof(char)就是为arr数组开辟的
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	//使用
	ps->n = 100;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = 'a';
	}
	for (i = 0; i < 10; i++)
	{
		printf("%c ", ps->arr[i]);
	}
	//增容
	struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 20 * sizeof(char));
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	else
	{
		ps = ptr;
	}
	//释放
	free(ps);
	ps = NULL;
	return 0;
}

三:模拟实现柔性数组

struct S
{
	int n;
	char* arr;
};

int main()
{
	struct S* ps = (struct S*)malloc(sizeof(struct S));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	//为arr开辟指向的空间
	ps->arr = (char*)malloc(sizeof(char) * 10);//开辟10个字符型的空间
	if (ps->arr == NULL)
	{
		perror("malloc");
		return 1;
	}
	//使用
	ps->n = 100;
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		ps->arr[i] = 'a';
	}
	for (i = 0; i < 10; i++)
	{
		printf("%c ", ps->arr[i]);
	}
	//增容
	char* ptr = (char*)realloc(ps->arr, sizeof(char) * 20);
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	else
	{
		ps->arr = ptr;
	}
	//使用
	for (i = 0; i < 20; i++)
	{
		*((ps->arr)+i) = 'b';
	}
	for (i = 0; i < 20; i++)
	{
		printf("%c ", *((ps->arr) + i));
	}
	//释放
	free(ps->arr);
	ps->arr = NULL;
	free(ps);
	ps = NULL;
	return 0;
}

 常规的柔性数组,只需要malloc一次,free一次,并且空间是连续的,而模拟实现的柔性数组需要malloc两次,free两次,并且空间可能不连续。malloc的次数越多,越容易出错,可能出现忘记释放导致内存泄漏问题。此外,malloc的次数越多,产生的内存碎片就越多,内存利用率就会下降,造成内存空间浪费,malloc次数越少,产生的北村碎片就越少,内存利用率就会增加,会避免内存空间浪费。并且空间连续的情况下,访问数据的时候效率就会更高。

 今天的分享到这里就结束啦!如果觉得文章还不错的话,记得三连支持一下小恐龙,您的支持就是小恐龙前进的动力!


在这里插入图片描述

相关文章:

  • 2023​史上最全软件测试工程师常见的面试题总结​ 备战金三银四
  • Day12【元宇宙的实践构想01】—— 元宇宙概念和发展历程
  • 《从0开始学大数据》之如何自己开发一个大数据SQL引擎
  • websoket是干么的如何基于websoket实现一个简单的消息通信。
  • nacos 服务发现获取列表源码分析
  • 【MySQL】过年没有回老家,在出租屋里整理了一些思维导图
  • 《流浪地球 2》 Deepfake 小试牛刀,45+ 吴京「被」年轻,变身 21 岁小鲜肉
  • C++工程实践必备技能
  • GitHub访问问题与FastGithub下载及使用(详细篇)
  • <使用Python自定义生成简易二维码>——《Python项目实战》
  • Spring Boot 热部署(热加载)
  • 又一个开源工具搞完了,工作效率直接翻倍
  • 入职-环境安装篇
  • 自动驾驶感知——毫米波雷达
  • MySQL运维(二)MySQL分库分表概念及实战、读取分离详解
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Android Volley源码解析
  • Android 控件背景颜色处理
  • Angular4 模板式表单用法以及验证
  • C++类的相互关联
  • echarts花样作死的坑
  • Elasticsearch 参考指南(升级前重新索引)
  • Hibernate最全面试题
  • JavaScript 基本功--面试宝典
  • Java反射-动态类加载和重新加载
  • Java精华积累:初学者都应该搞懂的问题
  • mac修复ab及siege安装
  • Mocha测试初探
  • Node 版本管理
  • python学习笔记 - ThreadLocal
  • 分布式事物理论与实践
  • 后端_MYSQL
  • 将回调地狱按在地上摩擦的Promise
  • 买一台 iPhone X,还是创建一家未来的独角兽?
  • 前端
  • 前嗅ForeSpider中数据浏览界面介绍
  • 三栏布局总结
  • 事件委托的小应用
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • 用简单代码看卷积组块发展
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 《天龙八部3D》Unity技术方案揭秘
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • $ git push -u origin master 推送到远程库出错
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (多级缓存)缓存同步
  • (附源码)计算机毕业设计ssm电影分享网站
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (转)详解PHP处理密码的几种方式
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?