
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件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
自動変数はスタックから、newした場合はヒープからなんでしょけど、実際は最適化されて全然違う動きしてることもありますよ。
デバッグモードとリリースモードでも、メモリの取り方は変わってきますよ。
参考までに
No.4
- 回答日時:
ヒープやスタックかの話をするときは機器とOSと開発環境を限定してもらわないと回答が難しいと思って下さい。
C/C++の規格外の話なので環境依存するとしか言えないのです。開発環境 Visual Studio をVisualStudioに限定し、OSをWindows、機器をx84/x64アーキテクチャと言うことでよろしいですか?
そうするとautoなローカル変数はスタック上であると考えてもらえば良いと思います。ただし、スタックサイズはビルド時に変更できるので多少の融通は効きます。が、普通はこんなことはしません。ギリギリまで使ったら安全マージンがなくなりますから。
ローカル変数的なクラスのインスタンスも同様です。
No.3
- 回答日時:
> 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のような余裕のあるシステムでは、そうそう出るものではありません。
・大きな配列やクラスを自動変数として宣言しない
・再帰関数の呼び出しの深さに注意して、深くなりすぎないようにする
というのに気をつければ、まず発生することはありません。
No.2
- 回答日時:
C++ の規格 (とりあえず手元にある 14882:1998) に出てくる「スタック」や「ヒープ」って
・例外処理における専門用語としての「stack unwinding」と関連用語
・std::stack や優先準位キューがらみ (<algorithm> の std::make_heap など)
しかないんだよね.
さて, あなたの使ってる「スタック」とか「ヒープ」ってのは, これのことでいい?
この回答への補足
プログラムのメモリ配置でいう、スタックメモリとヒープメモリのことです。
「newやmallocを使うとヒープに確保される」というときに使う、ヒープメモリのことです。
ここに解説されている通りの内容です。
http://www.uquest.co.jp/embedded/learning/lectur …
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
allocってなんですか?
-
x64環境で連続4GB以上のメモリ...
-
OpenCV cvLoadImageについて
-
Excelですべての組合せ(重複組...
-
C言語において、 配列要素をひ...
-
C言語 配列の長さの上限
-
CStringからchar*への型変換に...
-
isalpha()関数について
-
配列を使わずに、変数名を動的...
-
C言語の配列のサイズ
-
Integer変数をカラにしたいので...
-
Run-Time Check Failure #3とい...
-
リッチテキストボックスの中身...
-
C# Listを使わずに2次元配列の...
-
define で 配列
-
文字列strの中から文字cを探す...
-
typedefをプログラム中で解除す...
-
c言語プログラミング 等差数列...
-
MSFlexGridのSortメソッドについて
-
「#undef」と「#define」の使い...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
allocってなんですか?
-
c言語のポインタへの文字列入力...
-
HEAP に関すること
-
構造体でchar name[]と*nameの...
-
ビットをローテートするプログ...
-
ヒープメモリの解放について
-
DLLのマルチスレッドの動作につ...
-
グローバル変数のサイズ
-
C++で、メンバもヒープに確保さ...
-
newしないオブジェクトについて
-
free関数で動作が止まる
-
構造体配列の初期化について
-
void*型のデータサイズ
-
MFCのCStringについて
-
mallocで確保するメモリの領域...
-
CreateFileMapping について
-
LPWSTRのコピー
-
c言語のメモリの確保について
-
配列の添え字の最大数とは?
-
C言語の質問です。 以下の命令...
おすすめ情報