2012-06-24 16 views
8

mallocを呼び出すと、なぜ私はerror: flexible array member not at end of structエラーを受け続けるのだろうかと思います。可変長配列を持つ構造体があり、このエラーが発生しています。フレキシブルアレイメンバの構造エラーの終わりではない原因は何ですか?

構造体は、

typedef struct { 
    size_t N; 
    double data[]; 
    int label[]; 
} s_col; 

で、malloc関数の呼び出しは、

col = malloc(sizeof(s_col) + lc * (sizeof(double) + sizeof(int))); 

であるが、これはmalloc関数への正しい呼びますか?

答えて

14

構造体には1つのフレキシブルな配列メンバーしか配置できません。常に構造体の最後のメンバーでなければなりません。換言すると、mallocに電話する前にこのケースで間違ってしまったことがあります。実際にはmallocをこの構造体に対して正しく呼び出すことはできません。これはしかし多少異なること

struct my_pair { 
    double data; 
    int label; 
}; 

typedef struct { 
    size_t N; 
    struct my_pair data_label[]; 
}; 

注:代わりに、配列のあなたは(datalabel同じ数のメンバーの配列)したいように見えるものを

を行うには、のようなものを検討することもできdoubleの後にintの配列が続くと、1つの配列doubleとそれに続くintの配列が得られ、次にdoubleの次のintなどの配列が返されます。これが同じかそれほど近いかどうかは、どのようにデータを使用しているかによって異なります(たとえば、連続した配列を必要とする外部関数に渡す場合は、多分別々に行う必要があります)。

3
typedef struct { 
    size_t N; 
    double data[]; 
    int label[]; 
} s_col; 

あなたが途中で 可撓性アレイ部材(double data[])を有することができません。ハードコードされた配列サイズを考慮するかdouble *data

+0

私は "T * var"は "T var []"と同じであると教えています – spectre

+1

@ lukasz1985:あなたが言うことは、関数引数の文脈で真実であり、ポインタを用いて技術的に実現される「配列操作引数」を含む。通常(ここでは)配列は配列で、ポインタはポインタです。 – stan423321

2

構造体の定義と構造体の先頭へのポインタを指定すると、Cコンパイラは他のものにアクセスすることなく構造体の任意のメンバーにアクセスできる必要があります。構造内の各アイテムの位置は、それに先行するアイテムの数とタイプによって決まるので、アイテムにアクセスするには、すべての先行アイテムの数とタイプを知る必要があります。最後の項目が配列である特定の場合、配列内の項目にアクセスするには開始位置を知る必要があります(の数と型がの項目の前にあることを知る必要があります。配列自体について)、およびアイテムインデックス(コンパイラは、配列サイズについて何も知らなくても、スペースが存在するアイテムの数よりも小さいと想定することがあります)。しかし、構造体の終わり以外にFlexible Array Memberが現れた場合、それに続く項目の位置は、配列内の項目の数に依存します。コンパイラが知り得ないものです。

関連する問題