こんにちは。
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で質問しましょう!
似たような質問が見つかりました
- 経済学 ある経済の消費関数がC=a+c(Y−T)C=a+c(Y−T)の形で与えられている. ただし, a,c 1 2023/01/11 20:42
- CPU・メモリ・マザーボード 「コンピューターのメモリが不足しています」 5 2022/12/15 10:10
- CPU・メモリ・マザーボード 「コンピューターのメモリが不足しています」 3 2022/12/15 22:07
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
- 弁護士・行政書士・司法書士・社会保険労務士 募集株式の発行 取締役会議事録について 募集事項 増加する資本金及び資本準備金に関する事項について 1 2022/06/06 01:25
- 数学 数学についての質問です。 変化の割合の公式の a=yの増加量/xの増加量 は一次関数に使えるのは知っ 2 2022/05/08 16:20
- 化学 XRD分析の非晶質量と格子定数の関係 1 2023/01/17 10:09
- 数学 三次関数のグラフ 微分した二次関数の=0の解が1つ(重解)の時 元の三次関数のグラフはなぜ単調に増加 4 2023/05/11 11:04
- ダイエット・食事制限 見た目は痩せたのに体重は増えている。しかも筋トレしたわけではないので、筋肉で引き締まって増えたわけで 2 2023/05/30 22:54
- 経済学 マクロ経済の生産関数に関する問題がわかりません 1 2023/01/21 17:10
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
イベントにAddHandlerされてい...
-
C++ protectedにアクセス不可
-
既定のコンストラクタがない?
-
エディットコントロールでEnter...
-
VC6 コンパイルエラー C2248に...
-
コンソールアプリでのクリップ...
-
MFCのCListCtrlでスクロールを検出
-
FriendとPublicの違い。。。
-
このコンパイルエラーの意味に...
-
C#とC++/CLIの連携について
-
メンバ変数のサイズの増加
-
オブジェクト指向 集約の実装...
-
DebugクラスとTraceクラスの違い
-
オーバーライド関数の呼び出し...
-
スプラッシュコントロールの挿...
-
クラスのアドレスを引数として...
-
派生クラスから基本クラスprote...
-
オブジェクト型の変数が定義さ...
-
C# フォームのShow()のオーバー...
-
VB.NETで、DLLを頂いたんですが...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
FriendとPublicの違い。。。
-
既定のコンストラクタがない?
-
(UWSC) 「#32770」の意味わかり...
-
クラスのアドレスを引数として...
-
エディットコントロールのイベ...
-
ダイアログ表示時にチェックボ...
-
イベントにAddHandlerされてい...
-
ダイアログクラスのコントロー...
-
C++ protectedにアクセス不可
-
DebugクラスとTraceクラスの違い
-
DataGridViewのセルに斜線を引...
-
【ASP.NET】 独自で作成したク...
-
このコンパイルエラーの意味に...
-
エディットコントロールでEnter...
-
継承を重ねた場合のコストはど...
-
C#で通常のbuttonコントロール...
-
ボタンのオーナードローについて
-
MFCのCListCtrlでスクロールを検出
-
【C++】相互参照
-
SetTimerの行でアサートエラー...
おすすめ情報