什么是柔性数组

发布于:2022-10-29 ⋅ 阅读:(469) ⋅ 点赞:(0)

在这里插入图片描述

本期介绍🍖

主要介绍:什么是柔性数组,使用柔性数组的前提条件有哪些,柔性数组的特点是什么,柔性数组相较于一般实现有哪些优点👀。


  柔性数组是一种动态可变的数组,也许你从来没有听说过这个概念,但是它确实是存在的,是在C99标准底下支持的一种语法。想要使用柔性数组需要满足3个条件:

  1. 柔性数组只能存在于结构体内,且必须是结构体最后一个成员
  2. 柔性数组成员前,至少存在一个其他成员
  3. 数组的大小未定义

  例如:

typedef struct st_type
{
 	int i;
 	int a[0];//柔性数组成员
}type_a;

  有些编译器会报错无法编译,可以改成如下形式:

typedef struct st_type
{
 int i;
 int a[];//柔性数组成员
}type_a;

  柔性数组的特点:

  1. 使用sizeof计算包含柔性数组的结构体的大小,得出的结果不包含柔性数组的内存

在这里插入图片描述

  1. 包含柔性数组成员的结构体要用malloc函数来进行内存的动态分配,并且分配的内存应大于结构体的大小,以适应柔性数组的预期大小。如下所示:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>

typedef struct st_type
{
	int i;
	int a[0];//柔性数组成员
}type_a;

int main()
{
	type_a* ptr = (type_a*)malloc(sizeof(type_a) + 100 * sizeof(int));
	if (ptr == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	ptr->i = 100;
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		ptr->a[i] = i + 1;
	}
	free(ptr);
	ptr = NULL;
	return 0;
}

  那为什么要以动态内存的方式来为这种结构体开辟空间,而不是用原先的方式直接开辟? 通过其内存布局就很容易理解了:
在这里插入图片描述

  柔性数组就是以这种内存空间不断的变化,来使得整个数组拥有了动态的性能,某种意义上相当于该数组柔软可变的,所以称为柔性数组。注意:若直接用这种包含柔性数组的结构体类型来创建变量,那么该结构变量相当于只有一个成员i由于该类型结构体的大小不包含柔性数组,故在像内存申请空间时,自然也不会获得柔性数组的空间,所以该结构体变量相当于就只有一个成员i)。


  其实我们完全可以用柔性数组结构体,来代替下面这种结构体的用法:

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

typedef struct st_type
{
	int i;
	int* a;
}type_a;

int main()
{
	type_a ptr;
	ptr.a = (int*)malloc(100 * sizeof(int));
	if (ptr.a == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	ptr.i = 100;
	int i = 0;
	for (i = 0; i < 100; i++)
	{
		ptr.a[i] = i + 1;
	}
	free(ptr.a);
	ptr.a = NULL;
	return 0;
}

  这种结构体用法的内存布局为:
在这里插入图片描述

  我们发现使用柔性数组实现的结构体,一整个都是在堆区上开辟的,而且是一块连续的空间。而用结构体中包含指向动态内存的指针的方法,是分为两块不同的区域来开辟的,结构体是在栈区上申请的,而其中指针成员维护的那块空间是在堆区上申请的。相比较这两种写法,柔性数组的好处是:有利于访问速度(其实,我个人觉得也没多高了,反正你跑不了要用做偏移量的加法来寻址)。

  下面我给出一个链接,让大家更深入的了解一下C语言《C语言结构体里的成员数组和指针》


在这里插入图片描述

这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。


网站公告

今日签到

点亮在社区的每一天
去签到