我阅读了以下代码:
struct hello {
int number;
int data[1];
};
我知道Flexible数组成员允许我们可以将最后一个元素声明为array of unspecified size
,如下所示:
struct hello {
int number;
int data[];
};
在这个struct
中,最后一个元素没有指定大小,那么这两个元素有什么区别?第一个声明是什么意思?
答案 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
D
中D
的格式为D1 [ constant-expressionopt] attribute-specifier-seqopt
....... 如果存在常量表达式(5.19),则它应为整数常量表达式,其值应大于零。
答案 2 :(得分:0)
它不是一个灵活的数组成员,但在一些需要与旧编译器或c ++编译器一起使用的代码中使用。
将其用作灵活的数组成员可能会引发未定义的行为。在实际代码中,这应该按预期工作,因为这个技巧被用在太多的代码中,以便编译器做出任何意想不到的事情。
答案 3 :(得分:0)
即使您只访问第一个元素,两者在C中也不完全等效。灵活阵列可以具有与固定大小阵列不同的对齐。因此,即使sizeof
可以为您提供不同的结果,也不应该在同一代码中混合使用这两个变体。