c语言柔性数组

柔性数组

在c99中,结构体的最后一个元素允许是未知大小的数组,这个就是柔性数组

 柔性数组的特点

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

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

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

柔性数组的声明

struct S
{
	int n;
	int arr[];//这里不指定数组的大小
};

有些编译器支持上面的写法,有些编译器支持下面的写法

struct S
{
	int n;
	int arr[0];
};

柔性数组的大小

struct S
{
	int n;
	int arr[0];
};

int main()
{
	printf("%d ", sizeof(struct S));
	return 0;
}

 这里我们在计算结构中包含柔性数组的大小的时候,不计算柔性数组的内存

柔性数组的使用

struct S
{
	int n;
	int arr[];
};

int main()
{
	struct S* p = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(struct S));
	//                               为n开辟空间           为arr数组开辟空间
	if (p == NULL)
	{
		//这里判断
		perror("malloc");
		return 1;
	}
	//申请成功,使用
	p->n = 100;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		p->arr[i] = i + 1;
	}
	//空间不够,增容
	struct S* ptr = (struct S*)realloc(p, sizeof(struct S) + 10 * sizeof(struct S));
	//这里先创建一个结构体指针变量接收realloc的返回值
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	//增容成功,使用
	p = ptr;
	for (i = 5; i < 10; i++)
	{
		p->arr[i] = i + 1;
	}
	//使用完毕,释放
	free(p);
	p == NULL;
	return 0;
}

这里,我们通过malloc函数申请空间,然后通过realloc函数来调节这个数组的大小,达到这个数组可以变长变短的效果,这个就是柔性数组。

结构体包含指针的形式模拟实现柔性数组的效果

我们可以不通过使用结构体中包含柔性数组的形式,我们通过结构体中包含指针也可以完成

struct S
{
	int n;
	int* arr;//这里我们创建一个数组指针
};

int main()
{
	struct S* p = (struct S*)malloc(sizeof(struct S));
	//这里我们先为结构体开辟空间
	if (p == NULL)
	{
		perror("malloc");
		return 1;
	}
	p->n = 100;
	//这里我们为数组指针指向的数组开辟空间
	p->arr = (int*)malloc(5*sizeof(int));
	if (p->arr == NULL)//判断是否开辟成功
	{
		perror("malloc");
		return 1;
	}
	//开辟成功,使用
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		p->arr[i] = i + 1;
	}
	//假设大小不够,进行增容
	int* ptr = (int*)realloc(p->arr, 10* sizeof(int));
	if (ptr == NULL)
	{
		perror("realloc");
		return 1;
	}
	//增容成功,使用
	p->arr = ptr;
	for (i = 5; i < 10; i++)
	{
		p->arr[i] = i + 1;
	}
	//这里我们需要先释放arr开辟的空间,在释放结构体开辟的空间
	//如果我们先释放了结构体开辟的空间,那么我们就找不到arr开辟的空间了,会造成内存泄漏的问日
	free(p->arr);
	p->arr = NULL;
	free(p);
	p = NULL;
	return 0;
}

柔性数组的优势

使用结构体包含指针的方式也可以完成结构体包含柔性数组的方式的效果,那么结构体包含柔性数组的优势是什么呢?

这里有两点优势

1.方便内存释放

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

2.有利于访问速度

连续的内存有利于提高访问速度,也有益于减少内存碎片。

如果malloc函数使用的次数越多,内存碎片就越多,那么内存的利用率就会越低

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++11:常用语法汇总

目录 &#x1f341;统一的列表初始化 { }initializer_list &#x1f341;decltype 推导表达式类型&#x1f341;可变参数模板解析可变参数包方法一方法二 &#x1f341;lambda 表达式捕捉列表的使用运用场景举例lambda表达式 与 函数对象 &#x1f341;统一的列表初始化 { } 在…

8个免费无版权视频素材网站,高清无水印视频任性下载

在数字化时代&#xff0c;优质的视频素材成为各种项目不可缺少的元素&#xff0c;从短片制作到商业广告&#xff0c;高品质的视频能显著提高作品的吸引力和传播效果。然而&#xff0c;寻找既免费又无版权问题的高清视频素材并非易事。以下介绍几个优秀的免费视频素材网站&#…

基于YOLOV8复杂场景下船舶目标检测系统

1. 背景 海洋作为地球上70%的表面积&#xff0c;承载着人类生活、经济发展和生态系统的重要功能。船舶作为海洋活动的主要载体之一&#xff0c;在海上运输、资源开发、环境监测等方面发挥着重要作用。复杂海洋环境下的船舶目标检测成为了海事管理、海洋资源开发和环境保护等领…

嵌入式全栈开发学习笔记---C语言笔试复习大全17

目录 指针和字符串 用数组和指针定义字符串 两种定义方法有什么区别&#xff1f; 第一个区别&#xff1a; 第二个区别&#xff1a; 第三个区别&#xff1a; 指针数组 上一篇复习了指针和数组,这一篇我们来复习指针和字符串。 说明&#xff1a;我们学过单片机的一般都是有…

(Java)心得:LeetCode——18.四数之和

一、原题 给你一个由 n 个整数组成的数组 nums &#xff0c;和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] &#xff08;若两个四元组元素一一对应&#xff0c;则认为两个四元组重复&#xff09;&#xff1a; …

【智能算法应用】基于果蝇算法-BP回归预测(FOA-BP)

目录 1.算法原理2.数学模型3.结果展示4.代码获取 1.算法原理 【智能算法应用】智能算法优化BP神经网络思路【智能算法】果蝇算法&#xff08;FOA&#xff09;原理及实现 2.数学模型 数据集样本特征数为13&#xff0c;适应度函数设计为&#xff1a; f i t n e s s e r r o…

推荐我常用的爬虫工具,三种爬虫方式,搞定反爬和动态页面

我和很多学python的同学聊过&#xff0c;至少有30%以上的人学Python是为了网络爬虫&#xff0c;也就是采集网站的数据&#xff0c;不得不说这确实是一个刚性需求。 但一个残酷的事实是&#xff0c;即使一部分人学了Python&#xff0c;掌握了requests、urllib、bs4等爬虫技术&a…

JUC下的Java java.util.concurrent.Locks详解

java.util.concurrent.locks 包介绍 java.util.concurrent.locks 包是Java并发编程中非常重要的一个部分&#xff0c;它提供了比内置synchronized关键字更为灵活的锁机制&#xff0c;用于多线程环境下的同步控制。这个包中最核心的是Lock接口&#xff0c;以及一系列实现类&…

整理好的中债国债3年期到期收益率数据集(2002-2023年)

01、数据简介 国债&#xff0c;又称国家公债&#xff0c;是由国家发行的债券&#xff0c;是中央ZF为筹集CZ资金而发行的一种ZF债券&#xff0c;是中央ZF向投资者出具的、承诺在一定时期支付利息和到期偿还本金的债权债务凭证。 中债&#xff0c;是指由中国中债登记结算有限责…

【ROS2】功能包

文章目录 ROS2 功能包创建功能包编译功能包设置环境变量功能包的结构C 功能包结构Python 功能包结构 参考链接 ROS2 功能包 在 ROS2 工作空间的 src 目录下进行编写的文件并不是普通的文件&#xff0c;而是被称作功能包。 创建功能包 Usage: ros2 pkg create --build-type …

【C/C++】内存分布

本文第一部分主要介绍了程序内存区域的划分以及数据的存储。第二部分有一段代码和一些题目&#xff0c;全面直观得分析了程序中的数组在内存中的存储。 因为不同的数据有不同的存储需求&#xff0c;各区域满足不同的需求&#xff0c;所以程序内存会有区域的划分。 根据需求的不…

线程同步--条件变量,信号量

生产者和消费者模型 案例 /*生产者消费者模型&#xff08;粗略的版本&#xff09; */ #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h>// 创建一个互斥量 pthread_mutex_t mutex;struct Node{int num;struct Node …

练习题(2024/5/12)

1二分查找 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4…

异常处理/ROS2异常处理模块源码解读与浅析

文章目录 概述ros2/rcutils/src/error_handling模块自身异常处理错误状态结构与存储本模块初始化错误状态的设置错误状态的获取错误状态的清理不丢失旧错误状态把手段还原为目的其他 概述 本文从如下几个方面对 ROS2.0 中 rcutils 库 error_handling 错误处理模块的源码进行解…

day-34 二叉树的锯齿形层序遍历

思路 相较于二叉树的层序遍历&#xff0c;多了一个flag变量,当flag等于0时&#xff0c;把当前层的数组从左到右放入链表&#xff0c;当flag等于1时&#xff0c;把当前层的数组从右到左放入链表。 解题方法 注意&#xff1a;链表删除一个数据后会立即重排&#xff0c;所以删除同…

Linux进程控制——Linux进程终止

前言&#xff1a;前面了解完前面的Linux进程基础概念后&#xff0c;我们算是解决了Linux进程中的一大麻烦&#xff0c;现在我们准备更深入的了解Linux进程——Linux进程控制&#xff01; 我们主要介绍的Linux进程控制内容包括&#xff1a;进程终止&#xff0c;进程等待与替换&a…

GoF之代理模式(静态代理+动态代理(JDK动态代理+CGLIB动态代理带有一步一步详细步骤))

1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09; 文章目录 1. GoF之代理模式&#xff08;静态代理动态代理(JDK动态代理CGLIB动态代理带有一步一步详细步骤)&#xff09;每博一文案2. 代理模式的理解3. 静态代理4. 动…

函数式接口-闭包与柯里化

闭包 定义 示例 注意 这个外部变量 x 必须是effective final 你可以生命他是final&#xff0c;你不声明也会默认他是final的&#xff0c;并且具有final的特性&#xff0c;不可变一旦x可变&#xff0c;他就不是final&#xff0c;就无法形成闭包&#xff0c;也无法与函数对象一…

单链表经典算法OJ题---力扣206,876(带图详解

1.链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;【点击即可跳转】 思路&#xff1a;创建三个指针&#xff0c;看下图 注意&#xff1a;n3如果为空&#xff0c;则不能继续指向下一节点&#xff0c;需要进行判断 代码实现&#xff1a; struct ListNode* reverseLi…

手游掘金最新玩法,单条视频变现1w+,一部手机即可操作,保姆级教程

如果你也想通过手机赚钱&#xff0c;在这里有一个非常好的项目&#xff0c;它可以让你轻松赚到额外的收入。 这个手游掘金最新玩法&#xff0c;是一个非常受欢迎的项目&#xff0c;它可以让你通过制作单条视频来获得高额收益。不同于传统的游戏赚钱方式&#xff0c;这个方法不…