c zero length array 零长度数组
struct userdata
{
uint32_t len;
uint8_t data[0];
};
在阅读一些开源代码时,比如linux kernel,会发现上面这种用法,这种叫做零长度数组。有什么作用呢?简单来说为了开发便利,顺便节省空间。
使用限制
只能放在结构体结尾,也就是一个结构体只能有一个零长度数组。
使用场景
比如我们有一个变长的数据块,如何保存这部分数据,有两种方案。
固定长度数组
struct userdata
{
uint32_t len;
uint8_t data[128];
};
可以定义一个最大长度的数组,每次把数据放到该数组中。有两个缺点
- 数据固定,如果超过最大值,会报错,需要重新修改代码编译。
- 浪费空间,正常情况都不会存满,导致内存浪费。
同样这种方式也有优点
- 更好的性能。用空间换时间,数据是提前分配好的,避免了申请时的再次分配。
指针形式
struct userdata
{
uint32_t len;
uint8_t * data;
};
这样在使用时现malloc申请空间,再赋值给data,缺点
- 多了一个指针,增加了空间占用
优点
- 灵活,可以放在任何位置,可以有多个
零长度数组
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
借用官方的示例说明以下,申请了一块空间,多出来的就是contents的内容。优点
- contents不占用空间,struct line的大小就是int length的大小。contents只是一个符号
- 数组空间不仅是动态的,还是连续的,更好的性能。使用指针,申请的空间与当前结构体不是连续的。
缺点
- 不够灵活,只能放在最后