c zero length array 零长度数组

发布时间 2023-12-26 16:34:16作者: 秋来叶黄
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只是一个符号
  • 数组空间不仅是动态的,还是连续的,更好的性能。使用指针,申请的空间与当前结构体不是连续的。

缺点

  • 不够灵活,只能放在最后

https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html