プロが教える店舗&オフィスのセキュリティ対策術

C++でどこまでヒープに確保されるのかが分からなくなる場合があります。

特に、配列がある場合や、クラスを使う場合newしてインスタンス作って使用する場合と、
そうでない場合があり、どこまでヒープ領域に確保されているのか
分からなくなってしまっています。

(開発環境 Visual Studio 2013等)


Q1 クラス内の配列

class AA{
public:
int x;
int dat[10];
};

AA *a0 = new AA();
とする場合と
AA a1;
とする場合。

このとき、メンバ変数はそれぞれ、
a0->xはヒープ領域に確保
a1.xはスタック領域に確保
されるという理解で良いですか?

そして、配列a0->dat[0]等 もヒープ領域に確保されていますか?


Q2 クラス内にクラス

class BB{
int u,v;
AA aa;
};

BB *b0 = new BB();
とした場合、

b0がヒープに確保されるとして、
b0->aaはヒープに確保されており、
b0->aa.xやb0->aa.dat[0]等もヒープに確保されているという
ことで良いでしょうか?

Q3 確認方法
変数等がヒープかスタック領域のどちらに確保されたかは
どうやって見分けることができますか?
アドレスの値から判断できますか?

よろしくお願い致します。

A 回答 (5件)

自動変数はスタックから、newした場合はヒープからなんでしょけど、実際は最適化されて全然違う動きしてることもありますよ。


デバッグモードとリリースモードでも、メモリの取り方は変わってきますよ。

参考までに
    • good
    • 0

ヒープやスタックかの話をするときは機器とOSと開発環境を限定してもらわないと回答が難しいと思って下さい。

C/C++の規格外の話なので環境依存するとしか言えないのです。

開発環境 Visual Studio をVisualStudioに限定し、OSをWindows、機器をx84/x64アーキテクチャと言うことでよろしいですか?

そうするとautoなローカル変数はスタック上であると考えてもらえば良いと思います。ただし、スタックサイズはビルド時に変更できるので多少の融通は効きます。が、普通はこんなことはしません。ギリギリまで使ったら安全マージンがなくなりますから。
ローカル変数的なクラスのインスタンスも同様です。
    • good
    • 0

> a0->xはヒープ領域に確保


> a1.xはスタック領域に確保

分けて考えているのが混乱の元。
メンバ変数は、クラスの一部です。
クラスがどうやって確保されたかを考えれば、メンバ変数がどこに確保されいるか、すぐわかるのでは。


int a[5] ;
とは、 sizeof(int) * 5 分の一塊の領域を「int が5つの配列」として使うためのもの。

class AA{
public:
int x;
int dat[10];
};
というのは、 sizeof(int)の一塊の領域とsizeof(int)*10の一塊の領域を含む、全体でsizeof(AA)の一塊の領域を使うためのものです。

> AA *a0 = new AA();
は、自動変数用の領域にsizeof(AA*)の一塊の領域が確保され、変数a0 という名前でアクセスできるようになります。
その内容は、 new AA()でnew/delete用の領域に確保された(そしてコンストラクタで初期化された)領域へのポインタになります。

> AA a1;
は、自動変数用の領域に sizeof(AA)の一塊の領域が確保され、変数a1 という名前でアクセスできるようになります。
その内容は、(コンストラクタで初期化された)AAです。



> BB *b0 = new BB();
> とした場合、
> b0がヒープに確保される

ポインタの場合は混同しないようにしましょう。
変数b0 自体は、自動のポインタ変数です。
自動変数用の領域にsizeof(BB*)の一塊の領域が確保されています。
その内容が new BB()で確保した領域のアドレスになっているのです。

BB b1 ;
*b0=&b1 ;
とすれば、 b0は b1のアドレス(=自動変数用の領域)になります。

------------
スタック、ヒープというのは、実装方法の一つであって、C++で決められたものではありません。
http://www.uquest.co.jp/embedded/learning/lectur …
> ヒープメモリについては、mallocなどのメモリ割り当て関数が、
> 開発環境(コンパイラ)に付属する標準ライブラリでサポートされている場合もあるんだけど、
> ない場合は自分で作る必要がある。
とあるように、mallocが「ヒープ」を使うとは限りません。

また、スタックオーバーフローは、スタックを使い過ぎたときに出るものです。
ですが、Windowsのような余裕のあるシステムでは、そうそう出るものではありません。
・大きな配列やクラスを自動変数として宣言しない
・再帰関数の呼び出しの深さに注意して、深くなりすぎないようにする
というのに気をつければ、まず発生することはありません。
    • good
    • 1

C++ の規格 (とりあえず手元にある 14882:1998) に出てくる「スタック」や「ヒープ」って


・例外処理における専門用語としての「stack unwinding」と関連用語
・std::stack や優先準位キューがらみ (<algorithm> の std::make_heap など)
しかないんだよね.

さて, あなたの使ってる「スタック」とか「ヒープ」ってのは, これのことでいい?

この回答への補足

プログラムのメモリ配置でいう、スタックメモリとヒープメモリのことです。
「newやmallocを使うとヒープに確保される」というときに使う、ヒープメモリのことです。

ここに解説されている通りの内容です。
http://www.uquest.co.jp/embedded/learning/lectur …

補足日時:2015/01/05 01:51
    • good
    • 0

>C++でどこまでヒープに確保されるのかが分からなくなる場合があります。



それを分かる必要がありますか?
C++の仕様としてはヒープとスタックの使い分けに関して何にも定義はありませんけど。

この回答への補足

分かる必要あります。

考慮しないでスタックを使いすぎるとスタックオーバーフローになってしまいます。

補足日時:2015/01/05 01:44
    • good
    • 0

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