• ベストアンサー
※ 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

  • メンバ変数に関して

    現在、C++にてプログラム作成しております。 1点プログラミングを行っている中で疑問になった点があります。 アイデア・方法等があれば教えて頂けると幸いです。 現在、メンバ変数として配列を定義したプログラムを作成しております。 そのメンバ変数を同クラス内のたくさんのメソッドから呼び出して処理を行っているのですが、そのメンバ変数の配列数を固定配列数ではなく、可変な配列数にしたいと考えております。 プログラムの実行後に取得した値をメンバ変数の配列数にしたいのです。 このように、メンバ変数の配列数の可変可を実施することは可能でしょうか?

  • 「引数の書き方」と「メンバ変数とメンバ関数の名前」について、教えてくだ

    「引数の書き方」と「メンバ変数とメンバ関数の名前」について、教えてください。 クラス内のコード抜粋なのですが、下記はどういう意味なのでしょうか? ▼メンバ変数 var $j = true; ▼メンバ関数 function j($p = false){ if($p) $this->j = false; return $this->j; } $this->j(true); 分からないこと ・コードの意味全般 ・($p = false)と書かれている引数の意味 ・メンバ変数とメンバ関数の名前は同じでもよいか? 

    • ベストアンサー
    • PHP
  • 外部からメンバ変数の中身を取得するには

    クラスAを作り、パブリックなメンバ変数valueを定義する。 ↓ クラスAのメンバ関数setvalueの引数をvalueに代入する。 ↓ クラスAを継承したクラスBを作り、そのメンバ関数内でvalueの中身を表示する。 これを正しく実現するにはどこに注意すればよいのでしょうか。自分で作ってみると、コンパイルエラーにはならないんですが、valueの中身が覚えのない巨大な数値で表示されてしまいます。

  • クラスのメンバになってくれません!

    クラスに変数名・関数名を入れれば自動的にクラスのメンバとしてくれるはずですよね。だけど、クラスメンバにしてくれません。 なぜでしょうか? たすけてください!おねがいします!

  • クラスのメンバ関数が多すぎる場合のデメリットはありますか?

    クラスのメンバ関数が多すぎる場合のデメリットはありますか? C++ であるクラスを実装してメンバ関数の追加を続けていたところ、メンバ関数の数が数十にまでふくれあがってしまいました。 このようにクラスのメンバ関数の数が多くなってしまった場合、パフォーマンス上でデメリットがありますでしょうか。 私としては、メンバ関数分だけメモリを食う、クラスのコピーが遅くなる、といいた点で心配なのですが実際のところどうなのでしょうか? (メンバ関数は、基本的にはクラスのメンバを操作するものなので、グローバル関数ではなくてクラスのメンバにしておいたほうが分かりやすいかなと思っています。)

  • ListBox内のobjectのメンバ変数

    VS2013 C# Windows Form Application での質問です ListBox内の項目に自作クラスPos(メンバ変数double x,y)を下記のように入れました listBox1.Items.Add(new Pos()); このとき double a = listBox1.~.x のようにlistBoxに入れたPosクラスのメンバ変数の値は取得できませんか?

  • 参照送りした構造体のメンバ変数の扱い方が

    自作関数に構造体のポインタを送り、メンバ変数の値を扱いたいのですが、 &で送り、*で受け取り、*とアロー演算子でメンバを指定しても 「error C2100: 間接指定演算子 (*) の使い方が正しくありません。」 と出てしまいます。 変数と構造体とでは勝手が違うのでしょうか? どうすればメンバ変数の値を扱えるのでしょうか。

  • PHP4で、メンバ変数の値を忘れてしまう2

    PHP4での質問です。 前の質問がわかりにくかったので、書き直しました。 オブジェクト指向的にいかがなものかとは思いますが、オブジェクトのメンバ変数を直接外部から変更したいと思います。 ---------<a.php>---------- class myClass {   var member = 0; } ---------<b.php>---------- $ary_c = array(); for ($i=0; $i<10; $i++) {   $c = new myClass();   $c->member = 1;   echo "(1)c->member=".$c->member;   array_push($ary_c, $c); } foreach ($ary_c as $c) {   echo "(2)c->member=".$c->member; } ------------------------------ 以上の様なソースで、(1)のデバッグライトでは、メンバ変数memberの値は1であるのに、(2)のデバッグライトでは、0になってしまいます。 この原因がお分かりのかた、もしよろしければ知恵をお貸し下さい。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • function内でメンバー変数を作れる?

    ActionScriptのオブジェクトスクリプトは初めてで、ActionScript2.0で制作しようとしています。 クラス内での変数の扱い方が解らずはまっています。 class Sample{ var temp:Array = Array(); function Func_01(key, val){ this.temp[key] = val; } 上の二行目メンバー変数tempを定義する部分をFunc_01内で行うことはできないのでしょうか? やりたいことは、外部テキストファイルを読み込み、中身によって持つメンバー変数を変えたいだけです。例えば 外部テキストより sample=key_A>>>1,key_B>>>2,key_C>>>3,key_D>>>4 を読み込み sample['key_A']=1; sample['key_B']=2; sample['key_C']=3; sample['key_D']=4; のように','と'>>>'でsplit等を利用し連想配列にして利用したいのですが、function内で読み込んだ値をメンバー変数にできずはまっています。お解りの方ご教授願います。

    • ベストアンサー
    • Flash
  • 構造体変数がないとメンバ操作できないのはなぜ?

    C言語の構造体に関して質問がありますが、structで型を作成して、構造体変数にてメンバの代入・参照をする。ということなんですが、なんでメンバ操作には構造体変数からでないといけないのでしょうか? 直接、型枠にてメンバ操作をすれば良いのに、なぜ構造体変数から操作しないといけないのでしょうか? 「クラス」や「オブジェクト」みたいに、一々ゼロから作成したり、コピペで作成しなくても済むように、このような形になっているのでしょうか? 回答の方よろしくお願いします。