首先,我们来看一个题

typedef struct list_t{
struct list_t *next;
struct list_t *prev;
char data[0];
}list_t;

此时,你知道32位系统中,sizeof(list_t)的值为多少么

这时,你会告诉我char data[0]在C和C++中是不被允许的,因为看起来毫无意义。然而,此处为何可以呢?

在讲述柔性数组成员之前,首先要介绍一下不完整类型(incomplete type)。不完整类型是这样一种类型,它缺乏足够的信息例如长度去描述一个完整的对象,它的出现反映了C程序员对精炼代码的极致追求,这种代码结构产生于对动态结构体的需求。

  鉴于这种代码结构所产生的重要作用,C99甚至把它收入了标准中。C99使用不完整类型实现柔性数组成员,在C99 中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组(flexible array)成员(也叫伸缩性数组成员),但结构中的柔性数组成员前面必须至少一个其他成员。柔性数组成员允许结构中包含一个大小可变的数组。柔性数组成员只作为一个符号地址存在,而且必须是结构体的最后一个成员,sizeof 返回的这种结构大小不包括柔性数组的内存。柔性数组成员不仅可以用于字符数组,还可以是元素为其它类型的数组。包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

并且柔性数组不占内存和内存对齐。而且使用柔性数组可以大大简化内容的管理,只需要一次申请,然后通过数组的指针偏移就可以直接获得相应的数据缓冲区,非常简单,释放的时候也仅仅只需要一次释放。