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 *foo
和char foo[]
在某些上下文中(例如函数参数声明)只是相同的东西而不是其他上下文(如结构字段声明)。
(我已经很长时间没有攻击C.)