Oracle Solaris Studio 12.2: C ユーザーガイド

D.1.8 柔軟な配列のメンバー

6.7.2.1 構造体および共用体の指示子

「struct hack」とも呼びます。構造体の最後のメンバーを、int foo[]; などのゼロ長の配列にすることができます。このような構造体は、malloc で割り当てられたメモリーにアクセスするためのヘッダーとして一般的に使用されます。

たとえば、struct s { int n; double d[]; } S; では、配列 d が不完全な配列型です。C コンパイラは、この S のメンバーのメモリーオフセットをカウントしません。つまり、sizeof(struct s)S.n のオフセットと同一になります。

d は、通常の配列メンバーと同様に、S.d[10] = 0; のように使用することができます。

C コンパイラが不完全な配列型をサポートしていない場合は、次の例の DynamicDouble のような構造体を定義および宣言します。


typedef struct { int n; double d[1]; ) DynamicDouble;

ここで、配列 d は不完全な配列型ではなく、1 つのメンバーを指定して宣言されています。

次に、ポインタdd を宣言してメモリーを割り当てます。


DynamicDouble *dd = malloc(sizeof(DynamicDouble)+(actual_size-1)*sizeof(double));

そのあとで、次のように S.n にオフセットのサイズを格納します。


dd->n = actual_size;

コンパイラが不完全な配列型をサポートしているため、1 つのメンバーを指定して配列を宣言することなく、同一の結果を得ることができます。


typedef struct { int n; double d[]; } DynamicDouble;

ここで、ポインタ dd を宣言し、前の場合と同様にメモリーを割り当てます。ただし、ここでは actual_size から 1 を引く必要はありません。


DynamicDouble *dd = malloc (sizeof(DynamicDouble) + (actual_size)*sizeof(double));

前の場合と同様に、オフセットは次のように S.n に保存されます。


dd->n = actual_size;