0

柔軟な配列メンバーを持つ構造体の配列を持つことはできません。

これは、この質問の TL;DR です。そしてそれについて考えると、それは完全に理にかなっています。

ただし、以下のように固定サイズの柔軟な配列メンバー ( swfamと呼びましょう) を持つ構造体の配列をシミュレートできます。

#include <assert.h>
#include <stdlib.h>


typedef struct {
    int foo;
    float bar[];
} swfam_t; // struct with FAM

typedef struct { // this one also has a FAM but we could have used a char array instead
    size_t size,  // element count in substruct
           count; // element count in this struct
    char data[];
} swfam_array_t;


#define sizeof_swfam(size) (sizeof(swfam_t) + (size_t)(size) * sizeof(float))


swfam_array_t *swfam_array_alloc(size_t size, size_t count) {
    swfam_array_t *a = malloc(sizeof(swfam_array_t) + count * sizeof_swfam(size));

    if (a) {
        a->size = size;
        a->count = count;
    }

    return a;
}

size_t swfam_array_index(swfam_array_t *a, size_t index) {
    assert(index < a->count && "index out of bounds");
    return index * sizeof_swfam(a->size);
}

swfam_t *swfam_array_at(swfam_array_t *a, size_t index) {
    return (swfam_t *)&a->data[swfam_array_index(a, index)];
}


int main(int argc, char *argv[]) {
    swfam_array_t *a = swfam_array_alloc(100, 1000);
    assert(a && "allocation failed");

    swfam_t *s = swfam_array_at(a, 42);

    s->foo = -18; // do random stuff..
    for (int i = 0; i < 1000; ++i)
        s->bar[i] = (i * 3.141592f) / s->foo;

    free(a);
    return 0;
}

トリックは有効な C99 / C11 ですか? 未定義の動作に潜んでいますか?

4

1 に答える 1

0

これを行う 1 つの方法は、柔軟な配列の代わりにポインター メンバーを使用することです。その後、malloc() などを介して手動でサイズを割り当てる必要があります。アル。[] は通常、配列が宣言で初期化される場合にのみ使用されます。これは、宣言ではなく本質的に定義である struct では不可能です。構造体型のインスタンスをすぐに宣言する機能は、定義の性質を変更しません。これは便宜上のものです。

typedef struct {
    int foo;
    float* bar; } swfam_t; // struct with FAM
于 2016-10-07T19:19:47.723 に答える