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

时间:2012-11-29 09:39:38

标签: c arrays struct

  

可能重复:
  Flexible array members in C - bad?

我阅读了以下代码:

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

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

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

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

4 个答案:

答案 0 :(得分:1)

这种阵列:

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 ++中,最好将动态分配的缓冲区包装在一个类中,这实际上是一种“黑客”。

答案 1 :(得分:0)

  

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

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

Raymond Chen answers it aptly

  

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

     

因为时间旅行尚未完善。

     

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

请注意,从技术上讲,第二个代码示例都不是有效的C ++代码。 [Ref 1] 但是许多现有代码都使用此功能,并且此代码几乎可以正常工作。


[参考1] 参考:

C ++ 11标准:8.3.4数组

  

在声明T DD的格式为

D1 [ constant-expressionopt] attribute-specifier-seqopt
     

.......   如果存在常量表达式(5.19),则它应为整数常量表达式,其值应大于零

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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