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

c语言中的柔性数组

也许你从来没有听说过 柔性数组( flexible array 这个概念,但是它确实是存在的。
C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
struct S
{
	int i;
	char ch[0];//char ch[]
};
int main()
{

	return 0;
}

上面一个结构体中最后一个未指定大小的数组就是柔性数组。上面的俩种方法都是可以的。

柔性数组的特点:
一 结构中的柔性数组成员前面必须至少一个其他成员。结构体成员中不能就会只有一名柔性数组成员,应该还包含其他的非柔性数组的成员。
struct s
{
	int arr[];
};

二、sizeof返回的这种结构大小不包括柔性数组的内存
所以,当你用sizeof来计算一个含有柔性数组成员的结构体大小时,计算出的结果不包括柔性数组成员在内。
比如:

struct S
{
	int i;
	char ch[0];//char ch[]
};
int main()
{
	printf("%zd\n", sizeof(struct S));//结果是4
	return 0;
}

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

struct S
{
	int i;
	char ch[0];//char ch[]
};
int main()
{
	struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(char));
	if (ps == NULL)//判断
	{
		perror("malloc");
		return 1;
	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(ps->ch) = 'Q';
	}
	for (i = 0; i < 10; i++)
	{
		printf("%c ", *(ps->ch));
	}
	free(ps);
	ps = NULL;
	return 0;
}

在图中开辟的前面的sizeof开辟的是int i的空间,后面一个是柔性数组的空间。然后我们可以开辟的10个空间打印10个字符Q。

模拟实现柔性数组的功能
其实,我们若不借用柔性数组也能实现以上功能:

typedef struct S
{
	int i;
	char* ch;
}S;
int main()
{
	S* ps = (S*)malloc(sizeof(S));
	if (ps == NULL)
	{
		perror("malloc");
		return 1;
	}
	ps->ch = (char*)malloc(sizeof(char) * 10);
		if (ps->ch == NULL)
		{
			perror("malloc");
			return 1;
		}
		int i = 0;
		for (i = 0; i < 10; i++)
		{
			*(ps->ch) = 'Q';
		}
		char* plc = (char*)realloc(ps->ch, 20 * sizeof(char));
		if (plc != NULL)
		{
			ps->ch = plc;
		}
		else
		{
			perror("realloc");
			return 1;
		}
		for (i = 0; i < 10; i++)
		{
			printf("%c ", *(ps->ch));
		}
		free(ps->ch);
		ps->ch = NULL;
		free(ps);
		ps = NULL;
	return 0;
}

柔性数组其实也就是结构体中的一个数组,准确来说,是一个空间大小可以自由变换的数组,那么我们在结构体中定义一个指针,使指针指向的空间可以自由变换(即指针指向的是动态开辟的内存),也就达到了这个效果。

注意: 这里释放动态内存空间时,需要先释放ps->ch指向的动态内存空间,再释放ps指向的动态内存空间。 如果我们先释放的是ps指向的动态内存空间,那么ps->ch所指向的空间就再也找不到了。

柔性数组的优点:

上述 代码 1 代码 2 可以完成同样的功能,但是 方法 1 的实现有两个好处:
第一个好处是: 方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给
用户。用户调用 free 可以释放结构体,但是用户并不知道这个结构体内的成员也需要 free ,所以你
不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好
了,并返回给用户一个结构体指针,用户做一次 free 就可以把所有的内存也给释放掉。
第二个好处是: 这样有利于访问速度 .
连续的内存有益于提高访问速度,也有益于减少内存碎片


http://www.kler.cn/a/389043.html

相关文章:

  • 【深度解析】CSS工程化全攻略(1)
  • 金价大跌,特朗普胜选或成导火索
  • uniapp 设置安全区域
  • 利用 Screen 保持 VSCode 连接远程任务持续运行
  • 使用Matlab神经网络工具箱
  • 现代Web开发:Vue 3 组件化开发实战
  • 【css flex 多行均分有间隙布局】
  • 小白学习之路:咖啡叶锈病分割
  • 105. UE5 GAS RPG 搭建主菜单
  • MySQL缓存参数如何优化与表结构如何优化才算是最大性能的优化
  • 6层板设计常用知识笔记
  • 鸿蒙开发基础入门
  • BP 神经网络学习 MATLAB 函数详解及应用
  • 【Istio】Istio原理
  • web安全漏洞之文件上传
  • 【JWT】Asp.Net Core中JWT刷新Token解决方案
  • DCN DCWS-6028神州数码 AC 设备配置笔记
  • ESLint 使用教程(三):12个ESLint 配置项功能与使用方式详解
  • SDL渲染器和纹理
  • 2024-11-10-leetcode每日一题-540. 有序数组中的单一元素
  • Python数据分析-Google Play商店应用数据分析
  • C#里对数组的排序操作
  • 关于我重生到21世纪学C语言这件事——函数详解
  • 初始JavaEE篇——多线程(8):JUC的组件
  • Python 获取PDF的各种页面信息(页数、页面尺寸、旋转角度、页面方向等)
  • jupyter添加、删除、查看内核