2016-10-07 18 views
0

フレキシブルな配列メンバーを持つ構造体の配列を持つことはできません。フレキシブルな配列メンバーを持つ構造体の配列として使用される汎用charバッファ

これはthis questionのTLです。それについて考えると、それは完璧な意味合いがあります。

はしかし、一つはは、柔軟な配列メンバーと構造体の配列をシミュレートすることができる - のは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ですか?私は未定義の行動に潜んでいますか?

答えて

0

これを行う1つの方法は、フレキシブルアレイの代わりにポインタメンバーを使用することです。その場合、malloc()などを使って手動でサイズを割り当てる必要があります。 al。 []は、通常、宣言で配列が初期化されたときにのみ使用されます。これはstructでは不可能です。これは本質的に宣言ではなく定義です。 struct型のインスタンスを即座に宣言することは、定義の性質を変えるものではなく、便宜上のものです。

typedef struct { 
    int foo; 
    float* bar; } swfam_t; // struct with FAM 
関連する問題