Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
644 views
in Technique[技术] by (71.8m points)

c - How does an array of structures with flexible array members behave?

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[];
};

The Wikipedia article says:

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

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

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.
", i, arr[0].array[i]);
        printf("    v0->data[%2zu] equals %2.0lf.
", i, v0->array[i]);
    }
    return 0;
}

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?

Extra: Read more about the flexible array in the OpenSTD C Spec.
Just search for 'flexible array member'.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

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.

Here is a modified version:

#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, i, arr[0]->array[i]);
        }
    }
    return 0;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...