1

このようなCの構造があるとします

struct A {  
int len;  
char s[1];  
}

上記の構造の配列が必要ですが、char s[1]構造体 A のメンバーは可変長にすることができます。どうすればこれを行うことができますか?C99 の struct ハック トリックでさえ、ここでは機能しないようです。1 つの解決策は、最後のメンバーとして動的メモリ割り当てを行うことですが、私の実装ではキャッシュを無視する必要があるため、char *すべてのデータを連続した場所に配置したいと考えています。struct

4

3 に答える 3

5

可変サイズのオブジェクトの配列を持つことはできないため、構造体ハックを使用して構造体の配列を持つことはできません。配列内のすべてのオブジェクトは同じサイズでなければなりません。そして、それらがすべて同じサイズである場合、サイズは構造体によって暗示されている必要があるため、構造体ハックを使用することはありません。構造体の配列の次元には 1 以外のサイズがありますs(1 がすべてに対して十分な大きさでない限り)。その理由は、a[i](aは配列の名前で、 は配列のインデックス) の格納場所は、「プラスのバイト アドレス (配列内の 1 つのオブジェクトのサイズを掛けた値) i」として計算可能でなければならないからです。したがって、配列内のオブジェクト (この場合は構造体) のサイズを把握し、固定する必要があります。ai

別の方法として、可変サイズのオブジェクトへのポインタの配列を持つことができます。各オブジェクトを適切なサイズで個別に割り当てるように調整し、そのポインタを配列に保存するだけです。

C99 は「構造体ハック」(公式には移植可能ではありませんでしたが、実際には移植可能でした) を廃止し、代わりに「柔軟な配列メンバー」を導入することに注意してください。

struct A {  
    int  len;  
    char data[];  
};

ただし、上記のアドバイスは引き続き適用されます。

于 2012-10-15T06:55:25.820 に答える
1

「s」の最大サイズがある場合は、[1]の代わりにそれを使用できます。それはすべてを連続させます。

ダイナミックメモリを本当に使用したくない場合は、配列を使用して使用することはできません。各メンバーに対して個別に構造体ハックトリックを使用する独自の「マネージャー」が必要ですが、インデックス付きルックアップを実行することはできません。各要素を調べて、その大きさを確認し、適切なバイト数をジャンプする必要があります。次の要素に。

于 2012-10-15T06:57:03.317 に答える
1

C では、配列のインデックス付けには、ベース アドレスに個々の要素のコンパイル時の定数サイズを掛けることが含まれます。そのため、組み込みの配列サポートを「構造体ハック」で直接使用することはできません。各s要素は、要求した 1 バイトに正確に割り当てられ、構造体のさらに先のインデックスSが配列内の次の要素にアクセスする (またはオフになる) ためです。完全に終了し、クラッシュする可能性があります)。

キャッシュアクセス速度のために連続したデータが本当に必要な場合は、自分でパックすることができます。これは(ほとんどのものと同様に)間接的に解決できます...の連続した配列を持ち、S*データを別の連続したバッファ(malloc()またはすべてのメンバーSの実際のデータ サイズを含め、すべてのオブジェクトに十分なメモリをスタック割り当てします)。要素がアーキテクチャに対して最適 (適切) に配置されていないs[]場合、パフォーマンスが低下する (または OS がクラッシュする)可能性があるため、インスタンス間で手動でパディングする必要がある場合があります。int lenS

S* index[100]               char data[10000];
(S*)(data)  --------------> S with 14-byte s[] using data[0]..[17]
(S*)(data + 20) -----\      2 byte padding so next S is 4-byte aligned
(S*)(data + 32) --\   \---> S with 7-byte s[] using data[20]..[30]
                   \        1 byte padding...
                    \-----> ...

s残念ながら、これは非常に柔軟性のないデータ レイアウトです。他のすべてのデータを邪魔にならないようにシャッフルしてインデックスにパッチを適用せずに要素のメンバーのデータ量を増やすことはできませんが、これは配列では正常なことです。それらを使用すると、おそらくこれがあなたに合うでしょう。もう1つの面倒は、構造体の合計サイズS(およびパディングを含むs[])を前もって計算することです....

于 2012-10-15T08:12:49.677 に答える