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

No.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では若干違うかも)
ただ、よっぽどのことがないかぎり、(アクセス効率が落ちるので)既定のアライメントを変更しないほうがいいです。
ファイルへのシリアライズやファイルからの逆シリアライズをする場合、パディングを取り除く目的でアライメント調整をするときには、処理系依存を覚悟で調整することもあります。が、仮想関数を持つ=仮想関数テーブルへのポインタを持つクラスに対してアライメント調整を行なうことはまずないかと。
返答ありがとうございます。
VC2003でそのような機能があるんですね。
アクセス効率が落ちるのでアライメントの調整は控えようと思います。
サイズが多少多くなりますが、アクセス効率が落ちるのはダメだと思うので。
No.3
- 回答日時:
ついでに。
sizeof(bool)も処理系依存。
処理系依存のようですね。
内はC++ bool型は1byteです。
VC++ 5.0以降は1byteらしいです。
BOOL型は4byteです。
No.2
- 回答日時:
いわゆる「アラインメント」の問題だろうと推測はできますが, 処理系が分からないので本当にその通りかどうかは知らない.
ちなみに (これも処理系に依存するが) 普通の処理系では仮想関数が増えてもクラスのサイズは増加しない.
この回答への補足
アライメントというのは、メンバ変数が一つでも起こるのでしょうか?
bool型一つ追加しただけで8byte確保したみたいなんですが、そういうこともあるんでしょうか?
処理はWindows XP SP3 VS.NET2003 PROです。
仮想関数は増えてもサイズは増加しないみたいですね。
アライメントを調べてみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# で 数式文字列処理を処理す...
-
Notepad++の関数リスト表示の変...
-
c#のTLS1.2での通信について
-
VisualStudioでC++クラスを追加...
-
Windows Formアプリからコンソ...
-
プログラマー達は何故、プログ...
-
C言語のことです。写真(見にく...
-
gccを行ってもexeファイルが生...
-
c言語
-
C++でデスクトップGUIアプリ開...
-
C言語 バッファについて。
-
visual studio 2022でのC#プロ...
-
プログラミングc++を全く分か...
-
C#でTreeViewのCheckBoxのサイ...
-
int16_t の _t は何?
-
DLLファイルの逆コンパイラにつ...
-
PIC12F1822でLED調光器を作りたい
-
c++の勉強方法を教えてくださ...
-
逆コンパイルと逆アセンブルの...
-
swift言語の最適化 swift最適化...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA チェックボックスをオーバ...
-
FriendとPublicの違い。。。
-
イベントにAddHandlerされてい...
-
既定のコンストラクタがない?
-
ダイアログ表示時にチェックボ...
-
(UWSC) 「#32770」の意味わかり...
-
【ASP.NET】 独自で作成したク...
-
エディットコントロールでEnter...
-
クラスのアドレスを引数として...
-
WindowsAPIのリストビューの...
-
エディットコントロールのイベ...
-
MFCアプリのコマンドラインでパ...
-
ボタンのオーナードローについて
-
正規表現 [^/]+ の意味を教えて
-
C++ protectedにアクセス不可
-
このコンパイルエラーの意味に...
-
MFCのドラッグ&ドロップについて
-
C# 別プロジェクトのフォームを...
-
オーバーライド関数の呼び出し...
-
MFCのCListCtrlでスクロールを検出
おすすめ情報