灵活的C结构arrays成员

从C-std节6.7.2.1引用,

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

这是一个有效的结构声明。 我正在寻找这种语法的一些实际用法。 确切地说,这个结构是如何保持一个双重的*作为第二个元素? 或者,这是另一种“你可以做多种方式”的情况吗?

Arpan

C FAQ正是回答了这个问题。 快速的答案是,这个结构将在结构中包含double数组,而不是指向结构外的数组的指针。 作为一个简单的例子,你可以像这个例子一样使用你的结构:

 struct s mystruct = malloc(sizeof(struct s) + 5 * sizeof(double)); sn = 12; sd[0] = 4.0; sd[1] = 5.0; sd[2] = 6.0; sd[3] = 7.0; sd[4] = 8.0; 

等等 – 你关心的数组大小包含在分配中,然后你可以像使用任何数组一样使用它。 通常这样的types包含了作为结构的一部分的大小,因为使用+技巧跳过typess的数组将会必然复杂。

对于你所加的问题,“这个构造如何构成比保持一个[指针]作为第二个元素更强大或者更弱的构造?”,它本身并没有更强大的function ,但是你不需要保留一个指针,所以你可以保存至less有那么多的空间 – 当你复制结构时,你也会复制数组,而不是指向数组的指针 – 有时会有微妙的差别,但是其他时候是非常重要的。 “你可以做多种方式”可能是一个很好的解释,但有些情况下,你会特别想要一个devise或另一个。

主要的优点是一个灵活的数组成员允许你为数组分配一块内存以及结构中的其他数据(带有指针,通常最后是两个单独分配的块)。

对于由很多networking协议传输的数据来说也是非常有用的,其中传入stream的定义方式是相同的 – 一个定义长度的整数,接着是许多单位(通常是字节/八位字节)的数据。 您可以(通常)使用types双精度来将具有灵活数组成员的结构覆盖到充满此类数据的缓冲区上,并直接使用它,而不必将其parsing为碎片,然后单独处理碎片。

您可以使用它来添加标题字段到dynamic分配的数组,其中最常见的是它的大小:

 struct int_array { size_t size; int values[]; }; struct int_array *foo = malloc(sizeof *foo + 42 * sizeof *foo->values); foo->size = 42; ... for(size_t i = 0; i < foo->size; ++i) foo->values[i] = i * i; 

你可以通过使用一个int *成员来实现类似的结果,并单独分配数组,但是在内存(额外的指针,第二个内存块的堆pipe理)和运行时(额外的间接,第二次分配)方面效率会更低。

我已经看到这在Windows上使用的长度标记的string。 字符数据直接存储在内存中,保持整齐。

 typedef struct { SIZE_T bytes; TCHAR chars[]; } tagged_string;