char指针与char数组不一样?

时间:2013-12-12 02:52:19

标签: c pointers struct redis flexible-array-member

阅读source code of Redis

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

我发现char buf[]无法替换为char *buf,因为char* buf会增加struct的大小。

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


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

  

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

使用char buf[]sdshdr len = 8输出sdshdr len = 16char *buf输出{{1}}。

1 个答案:

答案 0 :(得分:3)

声明buf成员的方式是利用名为灵活数组的C99功能,主要优势是获得use of variable length array like features inside a struct。由于声明buf没有大小,因此在动态分配 struct sdshdr * 时显式分配它之前不会占用空间。

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

6.7.2.1部分中的draft C99 standard有一个很好的示例,展示了如何使用此功能:

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).