C灵活数组与指针

struct ss { char foo[]; char bar[3]; int bazSize; char baz[]; } 

在上面,foo显然是4或8字节长的指针。 bar是一个数组,长度为3个字节。 baz曾经是一个8字节长的指针。 但在C99中,baz是一个灵活的arrays。 (传统上定义为baz [0]。)

规则是什么? 编译器如何知道foo是一种与baz完全不同的东西? 怎么能不破坏任何碰巧在结构的末尾有一个指针的代码呢? []现在与*不同吗?

您的结构声明不正确: char foo[]; 只能作为最后一个成员出现,并且它缺少一个; 在末尾。 这是正确的声明:

 struct ss { char *foo; char bar[3]; int bazSize; char baz[]; }; 

我们最后有一个指针foo和一个灵活的数组baz 。 当从堆中分配这样的结构时,最后一个成员的实际空间必须是已知的,并且如果不重新分配其结构,如果从其他各个地方引用的结构可能很复杂,则不能更改。 灵活的arrays可以节省空间,但根本不灵活

灵活arrays的优点:

  • 节省空间
  • 保存一个间接
  • 一步分配
  • baz永远不会是NULL

相反,使baz成为指针需要单独分配它指向的数组。 尺寸,代码和速度的这种缺点伴随着补偿。

指针版本的优点:

  • baz可以为NULL以指定无数据。
  • 当实际大小已知时,可以按需分配baz
  • baz可以很容易地重新分配。

所以你应该使用它取决于你如何使用这些结构。 使用时的语法是相同的,但编译器已经看到了实际的声明并将生成适当的代码。

首先,您需要初始化foo和baz以实际编译代码。 然后编译器清楚地知道两者之间的区别是什么。

问题是char *foochar foo[]在某些上下文中(例如函数参数声明)只是相同的东西而不是其他上下文(如结构字段声明)。

(我已经很长时间没有攻击C.)