结构体内长度为0的数组
参考资料
*结构体中数组下标为0
思考一种场景:需要一个结构体,结构体中的需要一个缓冲区,用于接收不定长数据。则最可能想到的就是两种解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #define MaxLength 1024 struct S1 { int len; int data[MaxLength]; };
int main() { int data[10] = { 0,1,2,3,4,5,6,7,8,9 }; int len = 10; struct S1* pS1; int data[10] = { 0,1,2,3,4,5,6,7,8,9 }; int len = 10; if (pS1 = (struct S1*)malloc(sizeof(S1))) { pS1->len = len; memcpy(pS1->data, data,sizeof(pS1->data[0])*len); } free(pS1); pS1 = nullptr; return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| struct S2 { int len; int* data; }; int main() { int data[10] = { 0,1,2,3,4,5,6,7,8,9 }; int len = 10; struct S2* pS2; if (pS2 = (struct S2*)malloc(sizeof(S2))) { if (pS2->data = (int*)malloc(sizeof(int) * len)) { memcpy(pS2->data, data, sizeof(int) * len); } } free(pS2->data); free(pS2); pS2 = nullptr; }
|
-
使用指针结果作为缓冲区, 只多使用了一个指针大小的空间, 无需使用 一定 长度的数组, 不会造成空间的大量浪费.
-
但那是开辟空间时, 需要额外开辟数据域的空间, 释放时候也需要显示释放数据域的空间, 但是实际使用过程中, 往往在函数中开辟空间, 然后返回给使用者指向 struct point_buffer 的指针, 这时候我们并不能假定使用者了解我们开辟的细节, 并按照约定的操作释放空间, 因此使用起来多有不便, 甚至造成内存泄漏。
定长数组使用方便, 但是却浪费空间, 指针形式只多使用了一个指针的空间, 不会造成大量空间分浪费, 但是使用起来需要多次分配, 多次释放, 那么有没有一种实现方式能够既不浪费空间, 又使用方便的呢?
GNU C 的0长度数组, 也叫变长数组, 柔性数组就是这样一个扩展. 对于0长数组的这个特点,很容易构造出变成结构体,如缓冲区,数据包等等:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| struct S3 { int len; int data[0]; }; int main() { int data[10] = { 0,1,2,3,4,5,6,7,8,9 }; int len = 10; struct S3* pS3; if (pS3 = (struct S3*)malloc(sizeof(struct S3) + sizeo (int) * len)) { memcpy(pS3->data, data, sizeof(int) * len); } free(pS3); pS3 = nullptr; return 0; }
|