目录
1.柔性数组
2.柔性数组的特点
3.柔性数组的使用
4.柔性数组的优势
C99 中,结构体中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。 例如:
struct S { char c; int n; int arr[];//柔性数组 }; struct S { char c; int n; int arr[0];//柔性数组 }; 有些编译器支持a[0]这种写法,有些编译器支持a[ ]这种写法,具体取决于编译器。
- 结构体中的柔性数组成员前面必须至少有一个其他成员。
- sizeof 返回的这种结构大小不包括柔性数组的内存。
- 包含柔性数组成员的结构用malloc 函数进行内存的动态分配,并且分配的内存应该大于结构体的大小,以适应柔性数组的预期大小。
例如:
#include struct S { int n; int arr[0];//柔性数组 }; int main() { printf("%zd\n", sizeof(struct S)); return 0; } 运行结果:
代码1:结构体里放数组
#include #include struct S { int n; int arr[0];//柔性数组 }; int main() { //期望数组可以存放5个元素 struct S* ps=(struct S*)malloc(sizeof(struct S) + 5 * sizeof(int)); if (ps == NULL) { perror("malloc"); return 1; } ps->n = 100; int i = 0; for (i = 0; i < 5; i++) { ps->arr[i] = i; } //调整空间 //期望数组可以存放10个元素 struct S* ptr=(struct S*)realloc(ps, sizeof(struct S) + 10 * sizeof(int)); if (ptr != NULL) { ps = ptr; } //使用 //释放 free(ps); ps = NULL; return 0; } 
通过realloc函数调整空间使数组变大变小,从而使柔性的特点更加鲜明,也不难想到它放在结构体中最后一个元素的原因。
内存窗口:
代码2:结构体里放指针
#include #include struct S { int n; int* arr; }; int main() { struct S* ps = (struct S*)malloc(sizeof(struct S)); if (ps == NULL) { perror("malloc"); return 1; } ps->arr =(int*) malloc(5 * sizeof(int)); if (ps->arr == NULL) { perror("malloc"); return 1; } //使用 ps->n = 100; int i = 0; for (i = 0; i < 5; i++) { ps->arr[i] = i; } //调整数组大小 int*ptr =(int*)realloc(ps->arr, 10 * sizeof(int)); if (ptr != NULL) { ps->arr = ptr; } //使用 //释放 注意:释放两块空间的先后顺序! free(ps->arr); ps->arr = NULL; free(ps); ps = NULL; return 0; }
注意:释放两块空间的先后顺序!如果先释放ps指向的内存空间,就找不到arr的值了,导致arr指向的内存空间无法释放。所以,要先释放arr指向的数组,再释放ps指向的内存。
上述代码1和代码2可以完成同样的功能,但是代码1的实现有两个好处:
1.方便内存释放
代码2里面做了二次内存分配,结构体内的成员也需要free,用户需要做两次free把内存释放掉,并且需要注意释放内存的顺序,而代码1用户做一次free就可以把所有的内存给释放掉。
2.有利于提高访问速度
连续的内存有益于提高访问速度,也有益于减少内存碎片。
上一篇:C语言 ——深入理解指针(2)