4

まず、構造体のバイトパディングを理解しています。しかし、私はまだ構造体に二重フィールドを含む小さなテストを持っており、これを説明する方法がわかりません:

typedef struct {
    char a;
    double b;
}data;

typedef struct{
    char a;
    int b;
}single;

int main(){
    printf("%d\n",sizeof(double));
    printf("%d\n",sizeof(single));
    printf("%d\n",sizeof(data));
}

このテスト全体を通して、答えは:8 816です。

なぜこの結果は私に考えさせますか?

2番目のテストでは、私のマシンのワードのサイズが4バイトであることがわかります。

最初のテストでは、doubleのサイズが8バイトであることがわかります。

したがって、構造体ではdata、結果は12バイトになります。charの場合は4バイト、doubleの場合は8バイトになります。

しかし、なぜ結果が16バイトになるのかわかりません。(私にはとても奇妙です)

説明してください、ありがとう:)

4

5 に答える 5

8

これは16バイトなので、datasの配列がある場合、double値はすべて8バイト境界に揃えることができます。データをメモリ内で適切に整列させると、パフォーマンスに大きな違いが生じる可能性があります。位置がずれているデータは、操作が遅くなり、フェッチと保存が遅くなる可能性があります。

于 2012-08-10T17:31:35.077 に答える
5

構造体にデータをレイアウトするために通常使用される手順は、基本的に次のとおりです。

  • オフセット=0に設定します。
  • 構造体の各メンバーの場合:Aをその配置要件とします(たとえば、1、2、4、または8バイト、場合によってはそれ以上)。オフセットに追加して、Aの倍数にするために必要なバイト数を追加します(Aが2の累乗である場合、これはOffset += -Offset & A-1、否定の2の補数を想定して、で実行できます)。オフセットの現在の値をオフセットに割り当てます。このメンバーの。メンバーのサイズをオフセットに追加します。
  • すべてのメンバーを処理した後:Aをメンバーの最大のアライメント要件とします。Aの倍数にするために必要なバイト数をオフセットに追加します。オフセットのこの最終値は、構造体のサイズです。

アーネストフリードマンヒルが述べたように、最後のステップでは、構造体の最後にパディングを追加して、それらの配列で、各構造体が必要な配置で開始するようにします。

したがって、のような構造体のstruct { char c; double d; int32_t i; }場合、一般的な実装では、次のようになります。

  • オフセットを0に設定します。
  • charには1の位置合わせが必要なので、オフセットはすでに1の倍数です(0•1は0です)。cをこのオフセット0に配置します。cのサイズ1をOffsetに追加して、1にします。
  • doubleには8の位置合わせが必要なので、オフセットに7を追加して8にします。このオフセットにdを追加します。8。オフセットにdのサイズ8を追加して、16にします。
  • intは4の位置合わせを必要とするため、オフセットはすでに4の倍数です(4•4は16です)。iをこのオフセット16に配置します。iのサイズ4をオフセットに追加して20にします。
  • 最後に、必要な最大の配置は8だったので、Offsetに4を追加して、24にします。この構造体のサイズは24バイトです。

上記は、マシンのワードサイズとは何の関係もないことに注意してください。各メンバーの配置要件のみを使用します。位置合わせの要件はタイプごとに異なる可能性があり、タイプのサイズとは異なる可能性があり、上記は引き続き機能します。

(アライメント要件が2の累乗でない場合、アルゴリズムは機能しません。これは、最後のステップでオフセットをすべてのアライメントの最小公倍数の倍数に増やすことで修正できます。)

于 2012-08-10T18:01:25.183 に答える
3

あなたにとって奇妙なことは何ですか(または私は何かが欠けています)?

ロジックは同じです(パディングは(つまり、int、double、charなど)の「最大の」プリミティブフィールドに従います)struct

のようにsingle、あなたは

1 (sizeof(char)) + 3 (padding) + 4 (sizeof(int))

それは同じですdata

1 (sizeof(char)) + 
7 (padding, it's sizeof(double) - sizeof(char)) + 
8 (sizeof(double))

これは16です。

于 2012-08-10T17:32:14.447 に答える
2

コンパイラーは、おそらくすべての構造体サイズを8の倍数になるように調整します

于 2012-08-10T17:32:02.373 に答える
2

コンパイラ固有のディレクティブを使用して明示的に指定しない限り、アライメントはコンパイラ次第です。

変数は必ずしも単語に揃えられているとは限りません。時々、それらは効率のために二重の単語で整列されます。フローティングポイントの特定のケースでは、SSEが機能するように、さらに高い値に揃えることができます。

于 2012-08-10T17:32:47.613 に答える