web-dev-qa-db-ja.com

構造体エラーの最後にないフレキシブルアレイメンバーの原因は何ですか?

なぜerror: flexible array member not at end of struct mallocを呼び出すとエラーが発生します。可変長配列の構造体があり、このエラーが発生し続けます。

構造体は、

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

そして、mallocの呼び出しは、

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

これはmallocの正しい呼び出しですか?

23
csta

構造体にはフレキシブル配列メンバーを1つだけ含めることができ、それは常に構造体の最後のメンバーでなければなりません。言い換えると、この場合、mallocを呼び出す前に、この構造体に対してmallocを正しく呼び出す方法が実際にはないという点で誤りがありました。

あなたが望んでいるように見えることを行うには(datalabelメンバーの数が同じ配列)、次のようなものを考えることができます:

struct my_pair { 
    double data;
    int label;
};

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

ただし、これは多少異なることに注意してください。doublesの配列の後にintsの配列が続く代わりに、1つのdoubleの後に1つのint、次のdouble、次のintなど。これが十分に近いかどうかは、データの使用方法に依存します(たとえば、連続した配列を期待する外部関数に渡す場合、おそらく別の方法で行う必要があります)。

25
Jerry Coffin

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

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

柔軟な配列メンバー(double data[]) 途中で。ハードコードされた配列サイズまたはdouble *data

3
J-16 SDiZ