具有灵活数组成员的结构数组如何表现?

Las*_*ive 5 c arrays struct flexible-array-member

正如标题所述,我想知道具有灵活数组成员的C结构数组如何表现.这是一个例子:

struct vector {
    size_t length;
    double array[];
};
Run Code Online (Sandbox Code Playgroud)

维基百科的文章说:

sizeof这种结构上的操作符需要给出柔性阵列成员的偏移量.

在我的机器上,这对应于8个字节(sizeof(size_t)).但是,当我执行以下操作时会发生什么:

显然,数组不能保存向量数据v0,因为它只有3*8字节= 24字节宽.我该如何处理这样的情况?

#define LENGTH 10

int main() {
    struct vector arr[3];

    struct vector *v0 = calloc(1, sizeof(*v0) + LENGTH * sizeof(v0->array[0]));
    v0->length = LENGTH;

    size_t i;
    for (i = 0; i < v0->length; i++) {
        v0->array[i] = (double) i;
    }

    struct vector v1;
    struct vector v2;

    arr[0] = *v0;
    arr[1] =  v1;
    arr[2] =  v2;

    for (i = 0; i < arr[0].length; i++) {
        printf("arr[0].array[%2zu] equals %2.0lf.\n", i, arr[0].array[i]);
        printf("    v0->data[%2zu] equals %2.0lf.\n", i, v0->array[i]);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

例如,当我正在编写一个库(header:mylib.h,source my lib.c:)并希望隐藏用户的一个特定结构的实现时(在头文件中声明的结构,在source-hidden中定义).遗憾的是,这个结构包含一个灵活的数组成员.当用户尝试创建命名结构数组时,这是否会导致意外行为?

额外:阅读有关OpenSTD C规范中灵活阵列的更多信息.
只需搜索" 灵活的阵列成员 ".

编辑:在C11标准的最新草案中,最最新的C语言免费提供参考,请访问:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570. PDF格式

chq*_*lie 7

以灵活数组作为最后一个成员的结构不能用作其他结构的成员或数组元素。在这种结构中,不能使用灵活数组,因为它的元素大小为 0。Jonathan Leffler 引用的 C 标准是明确的,尽管使用的语言相当技术性,并且通过搜索“ flexible”无法在标准中找到这些段落。

编译器应该为您的结构向量数组发出错误。

在您的程序中,您应该使用指向 的指针数组struct vectors,每个指针都指向为其灵活数组中的适当数量的元素分配的对象。

这是修改后的版本:

#include <stdio.h>
#include <stdlib.h>

struct vector {
    size_t length;
    double array[];
};

struct vector *make_vector(size_t n) {
    struct vector *v = malloc(sizeof(*v) + n * sizeof(v->array[0]));
    v->length = n;
    for (size_t i = 0; i < n; i++) {
        v->array[i] = (double)i;
    }
    return v;
}

int main(void) {
    struct vector *arr[3];

    arr[0] = make_vector(10);
    arr[1] = make_vector(5);
    arr[2] = make_vector(20);

    for (size_t n = 0; n < 3; n++) {
        for (size_t i = 0; i < arr[n]->length; i++) {
            printf("arr[%zu]->array[%2zu] equals %2.0lf.\n",
                   n, i, arr[0]->array[i]);
        }
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)