本期介绍🍖
主要介绍:什么是柔性数组,使用柔性数组的前提条件有哪些,柔性数组的特点是什么,柔性数组相较于一般实现有哪些优点👀。
??柔性数组是一种动态可变的数组,也许你从来没有听说过这个概念,但是它确实是存在的,是在C99标准底下支持的一种语法。想要使用柔性数组需要满足3个条件:
- 柔性数组只能存在于结构体内,且必须是结构体最后一个成员
- 柔性数组成员前,至少存在一个其他成员
- 数组的大小未定义
??例如:
typedef struct st_type
{
int i;
int a[0];
}type_a;
??有些编译器会报错无法编译,可以改成如下形式:
typedef struct st_type
{
int i;
int a[];
}type_a;
??柔性数组的特点:
- 使用
sizeof 计算包含柔性数组的结构体的大小,得出的结果不包含柔性数组的内存
- 包含柔性数组成员的结构体要用
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语言结构体里的成员数组和指针》。
这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏??,谢谢!!! 如果有什么疑问或不同的见解,欢迎评论区留言欧👀。
|