「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; |