这是C中的Flexible Array Struct成员吗?

可能重复:
C中的灵活arrays成员 – 糟糕吗?

我阅读了以下代码:

struct hello { int number; int data[1]; }; 

我知道Flexible数组成员允许我们可以将最后一个元素声明array of unspecified sizearray of unspecified size如下所示:

 struct hello { int number; int data[]; }; 

在这个struct ,最后一个元素没有指定大小,那么这两个元素之间的区别是什么? 第一个声明是什么意思?

这种数组:

 struct hello { int number; int data[]; }; 

只作为struct的最后一个元素才有意义,并且只有在从堆中分配struct时才会有意义,并且通常使得header字段包含数组的实际大小:

 struct hello *helloptr = malloc(sizeof (struct hello) + count*(sizeof int)); helloptr->number = count; 

用法是使用一个结构方便地分配头和数据缓冲区。

另外:与你的版本不同,它分配大小为1的数组是sizeof struct hello会更多,因为数组分配了一个元素而不是undefined = 0。 这要么浪费一个项目的内存,要么使大小计算更复杂,并且在概念上有点“难看”(你的代码有1个数组,当你实际意味着“未定义”,甚至可能是0)。

在OOP C ++中,最好将动态分配的缓冲区包装在一个类中,这实际上是一种“黑客”。

它不是一个灵活的数组成员,但在某些需要与旧编译器或c ++编译器一起使用的代码中使用。

将其用作灵活的数组成员可能会引发未定义的行为。 在实际代码中,这应该按预期工作,因为这个技巧被用在太多的代码中,以便编译器做出任何意想不到的事情。

data[1]data[0]什么区别?

差别是没有,两者都可以用于实现灵活大小的结构。

Raymond Chen 恰如其分地回答 :

好吧,你可能会说,为什么不使用零长度数组而不是1长数组呢?

因为时间旅行尚未完善。

零长度数组直到1999年才成为合法的标准C.由于Windows在很久以前就已存在,它无法利用C语言中的这种function。

请注意,从技术上讲,第二个代码示例都不是有效的C ++代码。 [参考1]但是现有的许多代码都使用了这个function,而且这段代码几乎可以使用。


[参考1] 参考:

C ++ 11标准:8.3.4数组

在声明T DD表示forms

 D1 [ constant-expressionopt] attribute-specifier-seqopt 

…….如果存在常量表达式(5.19),它应该是一个整数常量表达式, 其值应大于零

即使您只访问第一个元素,两者在C中也不完全等效。 灵活arrays可以具有与固定大小arrays不同的对齐。 因此,即使sizeof可以为您提供不同的结果,也不应该在同一代码中混合使用这两个变体。