dポイントプレゼントキャンペーン実施中!

  こんにちは。
 C++でクラスの大きさが重要になり、クラスのサイズを軽減しようとしていたんですが、メンバ変数
でbool型の変数を一つ追加しただけで 8byte増加してしまいました。
 何故、bool型なのに8byteも増加してしまったのかわかりません。
そのクラスには仮想関数が二つあります。
 それが原因で仮想関数が増すごとにクラスのサイズが増加するのは分かりますが、メンバ変数を一つ追加しただけで8byteも増加するのが理解できません。 その後bool型を追加したんですけどサイズは増えませんでした。
 bool型をそのまま増やして9個目からまた8byte増えるようです。
 何故1byteづつ増えていかないんでしょうか? よろしくお願いします。

A 回答 (4件)

下記【1】に簡単な説明がありますが、さらにかみ砕いて言うと、プロセッサによるデータ読み出しを高速化するために、大抵のコンパイラでは、構造体の全体のサイズがレジスタサイズの整数倍になるように、詰め物(パディング)が勝手に挿入されることが多いです。



【1】
http://www.office-matsunaga.biz/evctips/evctips0 …

ちなみに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では若干違うかも)

ただ、よっぽどのことがないかぎり、(アクセス効率が落ちるので)既定のアライメントを変更しないほうがいいです。
ファイルへのシリアライズやファイルからの逆シリアライズをする場合、パディングを取り除く目的でアライメント調整をするときには、処理系依存を覚悟で調整することもあります。が、仮想関数を持つ=仮想関数テーブルへのポインタを持つクラスに対してアライメント調整を行なうことはまずないかと。
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/01/14 16:46

ついでに。


sizeof(bool)も処理系依存。
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/01/13 22:24

いわゆる「アラインメント」の問題だろうと推測はできますが, 処理系が分からないので本当にその通りかどうかは知らない.


ちなみに (これも処理系に依存するが) 普通の処理系では仮想関数が増えてもクラスのサイズは増加しない.

この回答への補足

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

補足日時:2011/01/13 22:30
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/01/13 22:22

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

この回答への補足

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

補足日時:2011/01/13 22:47
    • good
    • 0
この回答へのお礼

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

お礼日時:2011/01/13 22:20

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!