柔性数组
1、零长度数组概念
0长度数组, 也叫柔性数组。
用途 : 长度为0的数组的主要用途是为了满足需要变长度的结构体
struct Packet { int state; int len; //cData就是柔性数组 char cData[0]; //这里的0长结构体就为变长结构体提供了非常好的支持 };
用法 : 在一个结构体的最后, 申明一个长度为0的数组, 就可以使得这个结构体是可变长的.
对于编译器来说, 此时长度为0的数组并不占用空间, 因为数组名本身不占空间, 它只是一个偏移量,
数组名这个符号本身代表了一个不可修改的地址常量。
注意 :数组名永远都不会是指针, 但对于这个数组的大小, 我们可以进行动态分配。
注意 :如果结构体是通过calloc、malloc或 者new等动态分配方式生成,在不需要时,要释放相应的空间。
优点 :比起在结构体中声明一个指针变量、再进行动态分 配的办法,这种方法效率要高。因为在访问数组内容时,不需要间接访问,避免了两次访存。
缺点 :在结构体中,数组为0的数组必须在最后声明,使 用上有一定限制。
2、零长度数组比较
// zero_length_array.c #include <stdio.h> #include <stdlib.h> #define MAX_LENGTH 1024 #define CURR_LENGTH 512 // 0长度数组 struct zero_buffer { int len; char data[0]; }__attribute((packed)); // 定长数组 struct max_buffer { int len; char data[MAX_LENGTH]; }__attribute((packed)); // 指针数组 struct point_buffer { int len; char *data; }__attribute((packed)); int main(void) { struct zero_buffer *zbuffer = NULL; struct max_buffer *mbuffer = NULL; struct point_buffer *pbuffer = NULL; // ===================== // 0长度数组 占用-开辟-销毁 // ===================== /// 占用 printf("the length of struct test1:%d\n",sizeof(struct zero_buffer)); /// 开辟 if ((zbuffer = (struct zero_buffer *)malloc(sizeof(struct zero_buffer) + sizeof(char) * CURR_LENGTH)) != NULL) { zbuffer->len = CURR_LENGTH; memcpy(zbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", zbuffer->len, zbuffer->data); } /// 销毁 free(zbuffer); zbuffer = NULL; // ===================== // 定长数组 占用-开辟-销毁 // ===================== /// 占用 printf("the length of struct test2:%d\n",sizeof(struct max_buffer)); /// 开辟 if ((mbuffer = (struct max_buffer *)malloc(sizeof(struct max_buffer))) != NULL) { mbuffer->len = CURR_LENGTH; memcpy(mbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", mbuffer->len, mbuffer->data); } /// 销毁 free(mbuffer); mbuffer = NULL; // ===================== // 指针数组 占用-开辟-销毁 // ===================== /// 占用 printf("the length of struct test3:%d\n",sizeof(struct point_buffer)); /// 开辟 if ((pbuffer = (struct point_buffer *)malloc(sizeof(struct point_buffer))) != NULL) { pbuffer->len = CURR_LENGTH; if ((pbuffer->data = (char *)malloc(sizeof(char) * CURR_LENGTH)) != NULL) { memcpy(pbuffer->data, "Hello World", CURR_LENGTH); printf("%d, %s\n", pbuffer->len, pbuffer->data); } } /// 销毁 free(pbuffer->data); free(pbuffer); pbuffer = NULL; return EXIT_SUCCESS; }
-
柔性数组并不占有内存空间, 而指针方式需要占用内存空间。
-
对于柔性数组, 在申请内存空间时, 采用一次性分配的原则进行; 对于包含指针的结构体, 才申请空间时需分别进行, 释放时也需分别释放。
-
对于柔性数组的访问可采用数组方式进行。
参考引用链接:
https://zhuanlan.zhihu.com/p/94855692
https://www.cnblogs.com/veis/p/7073076.html
https://blog.csdn.net/gatieme/article/details/64131322