1. 柔性数组的概念
也许你从来没有听说过柔性数组这个概念,但它确实是存在的。
C99中,结构体中的最后一个成员是允许未知大小的数组,这就叫做柔性数组成员!
typedef struct st_type { int i; int a[0];//柔性数组成员 }type_a;
有些编译器会报错无法编译可以改成~
typedef struct st_type { int i; int a[];//柔性数组成员 }type_a;
2. 柔性数组的特点
1 .结构体中柔性数组前面必须至少含有一个其他成员~
2. sizeof计算的结构体大小不包含柔性数组的大小~
struct s { int i; int a[]; }; int main() { printf("%zd\n", sizeof(struct s)); return 0; }
3. 包含柔性数组的结构体用malloc函数进行内存的动态分配,并且分配的内存必须大于结构体的内存,以适应柔性数组的预期大小~
4. 一个结构体中只能含有一个柔性数组
3. 柔性数组的使用
#include<stdio.h> #include<stdlib.h> #include<assert.h> struct s { int i; int a[]; }; int main() { //printf("%zd\n", sizeof(struct s)); struct s* p = (struct s*)malloc(sizeof(struct s) + 40); assert(p);//判断指针的有效性 p->i = 100; for (int i = 0; i < 10; i++) { p->a[i] = i + 1; } for (int i = 0; i < 10; i++) { printf("%d ", p->a[i]); } free(p); p = NULL; return 0; }
malloc在堆上是这样开辟空间的~
4. 柔性数组的优势
4.1上述功能的实现也可以用如下代码实现~
struct S { int i; int* arr; }; int main() { struct S* pa = (struct S*)malloc(sizeof(struct S)); assert(pa);//判断指针的有效性 pa->i = 100; pa->arr = (int*)malloc(40); assert(pa->arr); for (int i = 0; i < 10; i++) { pa->arr[i] = i + 1; } for (int i = 0; i < 10; i++) { printf("%d ", pa->arr[i]); } free(pa->arr);//释放空间 pa->arr = NULL; free(pa); pa = NULL; return 0; }
以上代码在堆上是这样开辟空间的~
上面俩段代码可以实现同样的功能~
4.2但使用柔性数组却有俩个好处~
其一:方便内存释放
如果我们的代码是在一个给别人用的函数中,你在里面做了⼆次内存分配,并把整个结构体返回给用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存⼀次性分配好了,并返回给用户⼀个结构体指针,用户做⼀次free就可以把所有的内存也给释放掉。
其二:这样有利于提高访问速度
连续的内存有利于提高访问速度,也有利于减少内存的碎片化。(其实,个人觉得也没有多高了,反正你跑不了要用偏移量的加法来寻址)