深入了解一下C语言中的柔性数组
Jambo! 人气:0什么是柔性数组
柔性数组是在C99中定义的
结构体的最后一个元素允许是未知大小的数组,这就叫柔性数组
柔性数组的长度可以写成0,也可以不规定数组长度
下面两种写法都是正确的
struct S { int i; int a[0];//柔性数组成员 }
struct S { int i; int a[];//柔性数组成员 }
- 结构体中的柔性数组成员前面至少有一个其他成员
- sizeof返回的这种结构体的大小不包括柔性数组的大小
- 包含柔性数组成员的结构体用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大
小,以适应柔性数组的预期大小。
柔性数组的使用
typedef struct S { int i; char c[];//c是柔性数组 }S; int main() { S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char)); if (p == NULL) { perror("malloc"); return 1; } p->i = 10; for (int i = 0; i < 10; i++) { p->c[i] = 'a'; } free(p); p = NULL; return 0; }
在malloc开辟空间时,开辟空间大小为sizeof(S) + 10 * sizeof(char),前面的sizeof(S)其实是表示结构体中int i的大小,后面则是给c开辟了10个字节大小的连续空间
如果觉得前面开辟空间小了,数组c不够长,还可以用realloc函数对内存大小进行调整
int main() { S* p = (S*)malloc(sizeof(S) + 10 * sizeof(char)); if (p == NULL) { perror("malloc"); return 1; } p->i = 10; S* ptr = (S*)realloc(p, sizeof(S) + 20 * sizeof(char)); if (ptr == NULL) { perror("realloc"); return 1; } p = ptr; for (int i = 0; i < 20; i++) { p->c[i] = 'a'; } free(p); p = NULL; return 0; }
其实我们也可以写出另一种形式的结构体,它的功能与柔性数组类似
typedef struct S2 { it i; char* c; }S2;
对于这个结构体的使用如下:
int main() { S2* p = (S2*)malloc(sizeof(S2)); p->i = 10; p->c = (char*)malloc(10 * sizeof(char)); for (int i = 0; i < 10; i++) { p->c[i] = 'a'; } free(p->c); p->c = NULL; free(p); p = NULL; return 0; }
为了使用这个结构体,需要先给结构体开辟一个空间S2* p = (S2*)malloc(sizeof(S2));然后再需要动态开辟一个块空间让c指向
这种写法需要开辟2次内存,同样在最后释放内存是,也需要free2次
所以就可以看出柔性数组的好处:
第 一个是方便内存释放
因为不论是我们在使用时或给别人写一个函数让别人使用时,如果在里面做了二次内存分配,可能别人使用时并不会知道结构体内部还有一个成员需要释放。所以就需要把内存一次性分配好,在最后释放一次内存就可以了
第二个是加快访问
如果二次内存分配,就会在内存中产生一些内存碎片,这样即浪费了空间也不利于访问
加载全部内容