0

可能重复:
C 中的灵活数组成员 - 不好?

我阅读了以下代码:

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

我知道灵活的数组成员允许我们声明最后一个元素是array of unspecified size这样的:

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

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

4

4 回答 4

1

这种数组:

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

仅作为结构的最后一个元素才有意义,并且仅在您从堆中分配结构时才有意义,并且通常使标头字段包含数组的实际大小:

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

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

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

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

于 2012-11-29T09:45:08.950 回答
0

data[1]和 和有什么不一样data[0]

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

Raymond Chen恰如其分地回答

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

因为时间旅行还没有完善。

零长度数组直到 1999 年才成为合法的标准 C。由于 Windows 早在那之前就出现了,它无法利用 C 语言中的这一功能。

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


[参考 1]参考:

C++11 标准:8.3.4 数组

在有表格的声明T DD

D1 [ constant-expressionopt] attribute-specifier-seqopt

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

于 2012-11-29T09:47:36.617 回答
0

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

于 2012-11-29T10:14:06.780 回答
0

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

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

于 2012-11-29T10:01:57.483 回答