3

阅读Redis 的源代码

struct sdshdr {
    int len;
    int free;
    char buf[];
};

我发现char buf[]不能用 替换char *buf,因为这char* buf会增加结构的大小。

但我不明白为什么,有人会对此有所了解吗?


编辑:我已经在我的 x86_64 Ubuntu(3.2.0-23-generic) 上使用 gcc 4.6.3 测试了它,如下所示:

printf("sdshdr len = %zu\n", sizeof(struct sdshdr));

char buf[]它输出sdshdr len = 8sdshdr len = 16char *buf.

4

1 回答 1

4

声明成员的方式buf是利用称为灵活数组的 C99 功能,主要优点是获得使用可变长度数组的功能,例如结构内的功能。由于声明时没有大小,因此在动态分配struct sdshdr *buf时显式分配它之前,它不会占用任何空间。

它比使用char *更有效,因为如果bufchar *,我们必须执行两次动态分配,首先是struct sdshdr *,然后buf指针本身需要额外的空间。这更干净,因为分配作为一个单元成功或失败,并且清理更简单,因为只free需要一个。我们还获得了数据的局部性,因为整个结构是在一个块中分配的,并且不需要单独取消对 access 的引用buf

部分C99 标准草案有一个很好的6.7.2.1例子,展示了如何使用这个特性:

EXAMPLE After the declaration:

   struct s { int n; double d[]; };

the structure struct s has a flexible array member d. A typical way to use this
is:

    int m = /* some value */;
    struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

and assuming that the call to malloc succeeds, the object pointed to by p
behaves, for most purposes, as if p had been declared as:

     struct { int n; double d[m]; } *p;

(there are circumstances in which this equivalence is broken; in particular, the
 offsets of member d might not be the same).
于 2013-12-12T03:02:35.340 回答