前言:
由于这块内容所谓综合性比较高,有数组的知识,有结构体的知识,还有动态内存管理的知识,所以我就单独写一篇博客,此谓番外篇。
柔性数组的概念
定义在结构体的最后一个元素的位置且大小未知的数组就叫柔性数组。
#include<stdio.h>
#include<stdlib.h>
struct test1
{int n;int arr[];//柔性数组
};struct test2
{int n;int arr[0];//柔性数组
};int main()
{return 0;
}
以上这两种定义的方式都是柔性数组,但可能有的编译器上并不是两种情况都支持。
柔性数组的特点
1.柔性数组的成员前边必须要有别的成员。
2.sizeof返回这种结构体的大小不会包括柔性数组的内存
3.必须要和动态内存分配(malloc函数等)一起结合使用。并且在动态分配内存大小的时候给柔性数组预留大小。
柔性数组的使用
如果有结构体或者动态内存管理等相关知识不知道的,可以去看一下我写的博客,链接如下。
C语言---自定义类型(上)(结构体类型)-CSDN博客
C语言---动态内存管理-CSDN博客
大家简单看一下我下边的代码(代码1)示例就懂柔性数组的基本使用了。
#include<stdio.h>
#include<stdlib.h>
struct test
{int n;int arr[];
};int main()
{//动态申请空间//前边半部分是给除去柔性数组的其他成员在堆区分配空间,后半部分申请的空间就给到的是结构体struct test* pt = (struct test*)malloc(sizeof(struct test) + 5 * sizeof(int));if (pt == NULL){//进入表示开辟空间失败perror("malloc");return 1;}//使用pt->n = 10;for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空间不够扩容struct test* ptr = (struct test*)realloc(pt, sizeof(struct test) + 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt = ptr;ptr = NULL;//释放空间free(pt);pt = NULL;return 0;
}
下边来看看内存里边大概是什么样子的
柔性数组的优势
先来看一下下边的代码(代码2),可以产生与刚才的柔性数组一样的效果。
#include<stdio.h>
struct test2
{int n;int* arr;//arr指针可以指向一块空间
};int main()
{//申请空间//给结构体整体分配空间struct test2* pt = (struct test2*)malloc(sizeof(struct test2));if (pt == NULL){perror("malloc1");return 1;}//使用pt->n = 10;//另外开辟一块空间让arr指针指向它pt->arr = (int*)malloc(5 * sizeof(int));if (pt->arr == NULL){perror("malloc2");return 1;}//使用arr指向的空间for (int i = 0; i < 5; i++){pt->arr[i] = i + 1;}//空间不够扩容int* ptr = (int*)realloc(pt->arr, 10 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}pt->arr = ptr;ptr = NULL;//使用................//释放//两次释放,先释放arr指向的空间,再释放结构体的空间free(pt->arr);pt->arr = NULL;free(pt);pt = NULL;return 0;
}
代码2的内存结构大致如下图
代码1和代码2有相同的效果,但很明显用代码1会更加好一点,也就是用柔性数组会更好一些,它的优势就是减少了内存碎片,提高访问速度,内存碎片就是指的每次动态内存申请的时候每一块空间之间的被浪费的间隙空间(不理解也没事),用柔性数组最大的好处就是方便内存释放,只需要free一次。