1. ホーム
  2. c++

[解決済み] 構造体のsizeofは、なぜ各メンバーのsizeofの合計と等しくないのですか?

2022-03-23 15:52:38

疑問点

なぜ sizeof 演算子は、構造体に対して、その構造体のメンバの合計サイズよりも大きなサイズを返すのですか?

どのように解決するのですか?

これは、アライメント制約を満たすためにパディングを追加しているためです。 データ構造のアライメント は、プログラムの性能と正しさの両方に影響を与えます。

  • 不整列なアクセスはハードエラーになる可能性があります(多くの場合 SIGBUS ).
  • 不整列なアクセスはソフトエラーの可能性があります。
    • ハードウェアで修正するか、適度な性能劣化のため。
    • または、ソフトウェアでエミュレートして修正し、性能劣化を激しくする。
    • また、アトミック性などの同時並行性の保証が破られ、微妙な誤差が生じる可能性があります。

以下は、x86プロセッサの典型的な設定を使用した例です(すべて32ビットと64ビットモードを使用)。

struct X
{
    short s; /* 2 bytes */
             /* 2 padding bytes */
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 3 padding bytes */
};

struct Y
{
    int   i; /* 4 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
    short s; /* 2 bytes */
};

struct Z
{
    int   i; /* 4 bytes */
    short s; /* 2 bytes */
    char  c; /* 1 byte */
             /* 1 padding byte */
};

const int sizeX = sizeof(struct X); /* = 12 */
const int sizeY = sizeof(struct Y); /* = 8 */
const int sizeZ = sizeof(struct Z); /* = 8 */

構造体のサイズを小さくするには,メンバをアライメントでソートすればよい(基本型ではサイズによるソートで十分)(例えば構造体 Z の例)。

重要な注意:CとC++の両標準は、構造のアライメントは実装によって決定されると述べています。 したがって、各コンパイラが異なるデータ配置を選択する可能性があり、その結果、異なる互換性のないデータレイアウトが発生します。 このため、異なるコンパイラで使用されるライブラリを扱う場合、コンパイラがどのようにデータを整列させるかを理解することが重要です。 コンパイラによっては、コマンドラインでの設定や特別な #pragma ステートメントを使用して、構造のアライメント設定を変更することができます。