0

次の構造を定義するとしましょう。

struct MyData { 
    int a;
    char b;
    int c;
    byte d;
    byte e;
}

その構造体のサイズは、データ型だけでなくメモリの配置にも依存することを読んだことを漠然と覚えています。32 ビット CPU では、MyData 構造は 4 バイト + 1 バイト + 4 バイト + 1 バイト + 1 バイト = 11 バイトになります。これが私の質問です。メモリの配置によって構造体のサイズが大きくなります: 4 バイト + 1 バイト (+3 バイトのパディング) + 4 バイト + 1 バイト (+3 バイトのパディング) + 1 バイト (+3 バイトのパディング) = 20 バイト。

これは間違っていますか?何か不足していますか?これは言語固有のものですか?構造体を梱包できますか? もしそうなら、長所と短所は何ですか?

ありがとう!

4

4 に答える 4

2

メモリ アラインメントによって構造体のサイズが大きくなる可能性があると述べたのは間違いではありません。ただし、メモリがどのように配置されるかについての推測は、すべてのプラットフォームで有効ではありません。これは厳密にプラットフォーム固有です。

基本的に、ほとんどのプラットフォームは ${WORDSIZE} に揃える傾向があります。または、データ型が ${WORDSIZE} より小さい場合は、${WORDSIZE} の次の利用可能な部分に揃えます。

たとえば、32 ビットのワードがあり、16 ビットの short を格納している場合、それらはワード内のビット 0 と 16 で整列する可能性があります。ただし、これは完全にプラットフォーム固有であるため、保証するものではありません。

パディングによる無駄が少なくなるように構造体を微調整するには、要素をデータ型で並べ替え、最初に大きなデータ型を使用します。これにより、複数のバイトを同じ単語にパックできる傾向があり (可能であれば)、単語アイテムよりも大きいアイテムは、単語のきれいな倍数 (クワッドワード、ダブルワードなど) になる傾向があるため、単語境界で適切に終了します。

于 2012-04-12T21:50:45.220 に答える
2

コンパイラは、適切と思われるように構造体をパディングできます。通常、最後byteの 2 つの はパディングで区切られないため、サイズは になり4 (int) + 1 (char) + 3 (padding) + 4 (int) + 1 (byte) + 1 (byte) + 2 (padding) = 16ます。

多くのコンパイラでは、プラグマごとに構造体をパックできます。その利点は、メモリ使用量が少ないことです。欠点は、アライメントされていないintメンバーの読み取りが遅くなることです。

于 2012-04-12T21:43:25.553 に答える
1

構造体メンバーの間と後に指定されていないパディングがあります。最初の構造体メンバーの前にパディングはありません。つまり、次のとおりです。

struct MyData bla;

int val = (char *) &bla == (char *) &bla.a;  // val is 1

(適切に変換された) 構造体へのポインターは、最初の構造体メンバーを指します。

構造体オブジェクトのサイズはパディングを考慮し、メンバーのサイズの合計 + 未指定のパディングのサイズの合計に等しくなります。

于 2012-04-12T21:42:03.730 に答える
0

はい、コンパイラは、サイズに一致する境界で型を自然に整列させます。次のようなコンパイラ プラグマを使用して、構造体のパッキングを強制できます。

#pragma pack(1)

また、宣言の順序を変更して int を先頭に、その後に 1 バイトを配置することで、パディングを回避することもできます。

これを印刷して簡単にテストできますsizeof(struct MyData)

于 2012-04-12T21:44:13.930 に答える