• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:メンバ変数のサイズの増加)

メンバ変数のサイズの増加

このQ&Aのポイント
  • C++でクラスのサイズを軽減しようとした際に、bool型の変数を追加しただけで8byte増加してしまいました。
  • クラスには仮想関数があり、仮想関数が増すごとにクラスのサイズが増加するのは理解できますが、メンバ変数を一つ追加しただけで8byteも増加するのが不思議です。
  • また、bool型の変数を追加した際はサイズが増えなかったのですが、9個目から再び8byte増えるようです。なぜ1byteずつ増えていかないのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • sygh
  • ベストアンサー率76% (42/55)
回答No.4

下記【1】に簡単な説明がありますが、さらにかみ砕いて言うと、プロセッサによるデータ読み出しを高速化するために、大抵のコンパイラでは、構造体の全体のサイズがレジスタサイズの整数倍になるように、詰め物(パディング)が勝手に挿入されることが多いです。 【1】 http://www.office-matsunaga.biz/evctips/evctips01.html ちなみにVisual C++ 2010の既定のコンパイル オプションでテストしたら下記のようになります。 とりあえずclassの代わりにstructを使っていますが、基本的にどちらも一緒です。 struct Test1 { }; struct Test2 { bool a; }; struct Test3 { bool a; bool b; }; struct Test4 { int x; bool a; }; #pragma pack(1) struct Test5 { int x; bool a; }; #pragma pack() struct Test6 { virtual ~Test6() {} }; sizeof(Test1) == 1; sizeof(Test2) == 1; sizeof(Test3) == 2; sizeof(Test4) == 8; sizeof(Test5) == 5; sizeof(Test6) == 4; // Win32(x86) sizeof(Test6) == 8; // x64 Test6構造体は仮想関数テーブルへのポインタを内部的に持っているため、x86とx64でサイズが異なります。 特定の構造体のアライメントを調整するには、Test5構造体のように(処理系依存の)#pragma packを使うことができます。 すべての構造体のアライメントを一括調整するには、コンパイル オプション(/Zp1~16)を使います。 (IDEから設定する場合、プロジェクト プロパティの「C/C++ ==> コード生成 ==> 構造体メンバーのアライメント」。VC 2003とVC 2010では若干違うかも) ただ、よっぽどのことがないかぎり、(アクセス効率が落ちるので)既定のアライメントを変更しないほうがいいです。 ファイルへのシリアライズやファイルからの逆シリアライズをする場合、パディングを取り除く目的でアライメント調整をするときには、処理系依存を覚悟で調整することもあります。が、仮想関数を持つ=仮想関数テーブルへのポインタを持つクラスに対してアライメント調整を行なうことはまずないかと。

DEADSPACE566
質問者

お礼

 返答ありがとうございます。 VC2003でそのような機能があるんですね。 アクセス効率が落ちるのでアライメントの調整は控えようと思います。 サイズが多少多くなりますが、アクセス効率が落ちるのはダメだと思うので。

その他の回答 (3)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

ついでに。 sizeof(bool)も処理系依存。

DEADSPACE566
質問者

お礼

処理系依存のようですね。 内はC++ bool型は1byteです。 VC++ 5.0以降は1byteらしいです。 BOOL型は4byteです。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

いわゆる「アラインメント」の問題だろうと推測はできますが, 処理系が分からないので本当にその通りかどうかは知らない. ちなみに (これも処理系に依存するが) 普通の処理系では仮想関数が増えてもクラスのサイズは増加しない.

DEADSPACE566
質問者

お礼

処理はWindows XP SP3 VS.NET2003 PROです。 仮想関数は増えてもサイズは増加しないみたいですね。 アライメントを調べてみます。

DEADSPACE566
質問者

補足

アライメントというのは、メンバ変数が一つでも起こるのでしょうか? bool型一つ追加しただけで8byte確保したみたいなんですが、そういうこともあるんでしょうか?

回答No.1

バイト境界が関係しているのでは。

DEADSPACE566
質問者

お礼

アドバイスありがとうございます。 さっそくその辺を調べてみます。

DEADSPACE566
質問者

補足

 クラスが継承されていて、その親クラスにdouble型のメンバ変数があるのですがそれが原因なんでしょうか?

関連するQ&A