简体   繁体   English

C灵活数组与指针

[英]C flexible arrays vs pointers

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

In the above, foo is clearly a pointer 4 or 8 bytes long. 在上面,foo显然是一个4或8个字节长的指针。 bar is an array, 3 bytes long. bar是一个数组,长3个字节。 baz used to be a pointer, 8 bytes long. baz以前是一个指针,长8个字节。 But in C99 baz is a flexible array. 但是在C99中,baz是一个灵活的数组。 (Traditionally defined as baz[0].) (传统上定义为baz [0]。)

What are the rules? 规则是什么? How does the compiler know that foo is a completely different type of thing than baz? 编译器如何知道foo和baz是完全不同的事物? How cannot this just break any code that happens to have a pointer at the end of a struct? 这如何不能仅仅破坏碰巧在结构末尾具有指针的任何代码? Is [] now different from *? []现在与*不同吗?

Your structure declaration is incorrect: char foo[]; 您的结构声明不正确: char foo[]; can only appear as the last member, and it is missing a ; 只能显示为最后一个成员,并且缺少; at the end. 在末尾。 Here is correct declaration: 这是正确的声明:

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

We have a pointer foo and a flexible array baz at the end. 我们在末尾有一个指针foo和一个灵活的数组baz When allocating such a structure from the heap, the actual space for the last member must be known and cannot be changed without reallocating the whose structure which may be complicated if the structure it referred to from various other places. 从堆分配这种结构时,必须知道最后一个成员的实际空间,并且在不重新分配其结构的情况下不能更改该空间,如果从其他地方引用该结构,则可能会很复杂。 Flexible arrays save space but are not flexible at all. 灵活的阵列可以节省空间,但一点也不灵活

Advantages of the flexible array: 灵活阵列的优点:

  • save space 节省空间
  • save one indirection 保存一个间接
  • allocate in one step 一步分配
  • baz is never NULL baz永远不会为NULL

Conversely, making baz a pointer requires separate allocation of the array it points to. 相反,使baz成为指针需要对其所指向的数组进行单独分配。 This disadvantage in size, code and speed comes with compensations. 大小,代码和速度上的此缺点带有补偿。

Advantages of the pointer version: 指针版本的优点:

  • baz can be NULL to specify no data. baz可以为NULL以指定没有数据。
  • baz can be allocated on demand, when the actual size is known. 当知道实际大小时,可以根据需要分配baz
  • baz can be reallocated easily. baz可以轻松地重新分配。

So which you should use depends on how you use these structures. 因此,应使用哪种取决于您如何使用这些结构。 The syntax at point of use is the same, but the compiler has seen the actual declaration and will generate the appropriate code. 使用时的语法相同,但是编译器已经看到了实际的声明,并将生成适当的代码。

Firstly, you need to initialise foo and baz for the code to actually compile. 首先,您需要初始化foo和baz才能真正编译代码。 Then it is clear to the compiler what the difference between the two are. 然后,编译器很清楚两者之间的区别是什么。

The problem is that char *foo and char foo[] are only the same thing in some contexts (like function parameter declaration) and not others (like structure field declarations). 问题在于char *foochar foo[]在某些上下文(例如函数参数声明)中只是同一件事,而在其他上下文(例如结构字段声明)中则不是。

(I have not hacked C for a long while.) (我已经很长时间没有破解C了。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM