C语言柔性数组介绍
2023-09-11 14:21:43 时间
柔性数组
也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。C99中,结构体中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。
//写法1
typedef struct st_type
{
int i;
int a[0];//柔性数组成员,大小未知
}type_a;
//写法2
typedef struct st_type
{
int i;
int a[];//柔性数组成员,大小未知
}type_a;
柔性数组的特点:
- 结构中的柔性数组成员前面必须至少有一个其他成员
- sizeof返回的这种结构大小不包括柔性数组的内存。
- 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。
typedef struct st_type
{
int i; //4
int a[0];//柔性数组成员
}type_a;
int main()
{
printf("%d\n",sizeof(type_a)); //输出的是4
return 0;
}
柔性数组的动态申请内存和使用
typedef struct S
{
int i;
int arr[0]; //柔性数组
};
int main()
{
//用malloc动态分配内存,期望arr的大小是10个整型
struct S* p = (struct S*)malloc(sizeof(struct S)+10*sizeof(int)); //申请空间:4(i)+10*4(arr) = 44
//使用...
p->i = 10;
for(int i = 0;i<10;i++)
{
p->arr[i] = i; //对柔性数组赋值
}
//增容
struct S* ptr = (struct S*)realloc(p,sizeof(struct S)+20*sizeof(int));
if(ptr != NULL)
{
p = ptr;
}
//使用增容后的空间...
//释放
free(p);
p = NULL;
return 0;
}
用普通代码实现柔性数组的功能
//实现柔性数组相同功能
struct S
{
int n;
int* arr;
};
int main()
{
struct S* p = (struct S*)malloc(sizeof(struct S));
if (p == NULL)
{
return 1;
}
p->n = 10;
p->arr = (int*)malloc(10 * sizeof(int)); //对指针arr再进行动态空间分配
if (p->arr == NULL)
{
return 1;
}
//使用
for (int i = 0; i < 10; i++)
{
p->arr[i] = i;
}
//增容
int* ptr = (int*)realloc(p->arr, 20 * sizeof(int));
if (ptr != NULL)
{
p->arr = ptr;
}
free(p->arr); //先释放arr指针指向的动态申请空间
p->arr = NULL;
free(p); //再释放整个结构体的空间,如果先释放结构体的空间,指针arr被释放了,则arr指向的空间就找不到了
p = NULL;
return 0;
}
普通代码实现相同功能与柔性数组的比较
- 普通代码需要两次malloc与free,比较容易出错,而柔性数组只需要一次malloc与free,方便内存的申请与释放
- 多次malloc在堆上申请空间时,会产生内存碎片,内存碎片被再次利用的概率小,会造成内存利用率降低(这里引申出软件设计上的内存池概念:在内存池里已经统一申请了多块空间,程序需要时直接拿去用就可以,用完后还回来,再统一释放,做到对内存的统一管理)
- 空间局部性:一块内存被访问后,其周边的内存很大概率会被再次访问;所以柔性数组在一次性malloc时变量的内存是连续的,对内存的访问速度一定程度上比较快,而多次malloc的内存空间可能是不连续的,此时对内存的访问效率会有一定影响
相关文章
- 计算机等级考试二级C语言程序设计专项训练题——数组元素的删除
- 计算机等级考试二级C语言程序设计专项训练题——数组元素的移动
- C语言批量数据到动态二维数组
- 数据结构之---C语言实现图的数组(邻接矩阵)存储表示
- C语言知识结构之二
- C语言两种导入头文件的区别
- C语言 内存分配 地址 指针 数组 参数 解析
- 怒肝20天用C语言写出的排序集合
- 【创】查并集byC语言
- 【C语言】零长度数组(可变数组,柔性数组)
- Android JNI编程(四)——C语言多级指针、数组取值、从控制台输入数组
- C语言:数组(2)
- 《C语言编程魔法书:基于C11标准》——2.6 大端与小端
- 《C语言解惑》—— 2.7 别混淆字符数组和字符
- 《C语言解惑》—— 2.8 一维数组更要特殊对待
- (第12列)C语言:定义结构体数组-----投票系统
- LeetCode数据结构_C语言题解系列-数组II&动态规划
- LeetCode数据结构_C语言题解系列-数组
- C语言 | 数组赋值方式
- C语言之数组练习题
- C语言--------一些指针和数组的题目解析
- 嵌入式C语言中用到的字符数组和字符指针再次总结
- 不用定时器和汇编语言,只用C语言实现精确无误的延时
- C语言遍历文件和文件夹——————【Badboy】
- 关于C语言中二维数组传參————————【Badboy】
- C语言文件操作
- C语言中整形数组、字符数组、字符串的区别
- 1028 人口普查 (20 分)C语言
- 1008 数组元素循环右移问题 (20 分)C语言
- java数组和C语言有什么区别?
- C语言指针和数组
- 【C语言&单片机杂谈】:char数组转换成HEX格式数据、C语言中什么情况下可以多赋值、 C语言中Switch中的 break和return的区别?C语言中类型转换?
- 【ESP32】Platformio+Arduino+LVGL | 如何加载图片(使用C语言数组方法)
- C语言编译的四个步骤
- 练习 1-8 编写一个统计空格、制表符与换行符个数的程序。// C语言