具有灵活数组成员的结构数组的行为如何? [英] How does an array of structures with flexible array members behave?

查看:37
本文介绍了具有灵活数组成员的结构数组的行为如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所述,我想知道如何使用 灵活数组成员行为.下面是一个例子:

As the title states I was wondering how arrays of C-structs with a flexible array member behaves. Here is an example:

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

维基百科文章说:

这种结构上的 sizeof 运算符需要给出灵活数组成员的偏移量.

The sizeof operator on such a struct is required to give the offset of the flexible array member.

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

On my machine this corresponds to 8 bytes (sizeof(size_t)). But what happens, when I do the following:

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

Obviously the array cannot hold the data of vector v0, since it's only 3*8 bytes = 24 bytes wide. How can I deal with situations like this?

#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;
}

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

For example, when I'm writing a library (header: mylib.h, source: my lib.c) and want to hide the implementation of one specific struct from the user (struct declared in header, defined in source - hidden). Sadly exactly this struct contains a flexible array member. Won't this lead to unexpected behavior, when the user tries to create an array of named structures?

额外:在 OpenSTD C 规范.
只需搜索'flexible array member'.

编辑:C11 标准的最新草案,C 语言的最新免费参考可在此处获得:http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

EDIT: The latest draft of the C11 Standard, the most up to date freely available reference for the C language is available here: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

推荐答案

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

Structures with a flexible array as their last member cannot be used as members of other structures or as array elements. In such constructions, the flexible array cannot be used as it has a size of 0 elements. The C Standard quoted by Jonathan Leffler is explicit, although the language used is quite technical and the paragraphs cannot be found in the Standard by searching for flexible.

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

The compiler should have issued an error for your array of struct vector.

在你的程序中,你应该使用一个指向struct向量的指针数组,每个指针指向一个分配给其灵活数组中适当数量元素的对象.

In your program, you should instead use an array of pointers to struct vectors, each pointing to an object allocated for the appropriate number of elements in the its flexible array.

这是修改后的版本:

#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;
}

这篇关于具有灵活数组成员的结构数组的行为如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆