ページ 1 / 1
その変数はスタックかヒープか
Posted: 2013年8月02日(金) 00:28
by 中級車
環境 windows7,VC++2008
疑問を以下のプログラムを例に説明します.何か知っている方がいましたら是非,参考にさせて頂きたいと考えております.
以下では,Testクラスを宣言し,メインでそのオブジェクトを作成しているのですが,
この変数「t1」はスタック領域の変数でしょうか?t2はヒープで,newで取得したので,deleteの必要があると思いますが・・・.またもしスタックだとすると,そのフィールドである,x,y,zはヒープということになるのでしょうか?これをどのように調べたり,又は知ることができるのか分かりません.
コード:
class Test{
private:
int *x;
int *y;
int *z;
int size;
Test(){}
Test(int i){
this.size=i;
this.x = new int[this.size];
this.y = new int[this.size];
this.z = new int[this.size];
for(int k=0;k<this.size;k++){
this.x[k] = 0;
this.y[k] = 0;
this.z[k] = 0;
}
}
~Test(){
delete[] x;
delete[] y;
delete[] z;
}
};
void main(){
Test t1(100);
Test t2 = new Test(100);
//以降でその他処理など
return;
}
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 00:32
by メリモ
基本的に変数自体はスタックですが、実体はヒープに格納される事が多いです。これはJavaでも一緒ですね。
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 00:35
by h2so5
まず this.x という書き方ではコンパイルが通らないはずです。 this->x の間違いでしょう。
t1はスタック領域の変数で、ポインタx, y, zもスタック領域にあります。 しかし、x, y, zが指している領域はヒープにあります。
t2はヒープ領域の変数で、ポインタx, y, zもヒープ領域にあります。 x, y, zが指している領域はヒープにあります。
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 00:36
by Poco
中級車 さんが書きました:
この変数「t1」はスタック領域の変数でしょうか?
そのフィールドである,x,y,zはヒープということになるのでしょうか?
共にYesです。
中級車 さんが書きました:
これをどのように調べたり,又は知ることができるのか分かりません.
VC++を使用する前提で、スタックに確保するオブジェクトであれば、アセンブラレベルでステップ実行し、
メモリの状態を確認すればできるんじゃないかな、と思います。
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 01:15
by 中級車
メリモ さんが書きました:基本的に変数自体はスタックですが、実体はヒープに格納される事が多いです。これはJavaでも一緒ですね。
ご回答有難う御座います.参考にさせて頂きます.
確かに・・・ローカルで宣言されていれば,変数自体はスタックと考えるのが自然ですよね,で,その中には確保されたヒープへのアドレスがあるという感じですかね・・・参考にさせて頂きます.
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 01:22
by 中級車
h2so5 さんが書きました:まず this.x という書き方ではコンパイルが通らないはずです。 this->x の間違いでしょう。
t1はスタック領域の変数で、ポインタx, y, zもスタック領域にあります。 しかし、x, y, zが指している領域はヒープにあります。
t2はヒープ領域の変数で、ポインタx, y, zもヒープ領域にあります。 x, y, zが指している領域はヒープにあります。
ご回答有難う御座います.参考にさせて頂きます.色々と雑な所があったので,プログラムについては以下に修正版を載せます.
ということはt1のフィールドx,y,zが指すヒープ領域は,t1をdeleteせずとも(というかできないが)mainが終わった時点で自動的にデストラクタにより,このプログラムの場合解放されるということですかね・・.
t2についてはmainの最後にdeleteが必要でそれによってデストラクタが呼ばれるということですかね・・.
コード:
class Test{
private:
int *x;
int *y;
int *z;
int size;
public:
Test(){}
Test(int i){
this->size=i;
this->x = new int[this->size];
this->y = new int[this->size];
this->z = new int[this->size];
for(int k=0;k<this->size;k++){
this->x[k] = 0;
this->y[k] = 0;
this->z[k] = 0;
}
}
~Test(){
delete[] this->x;
delete[] this->y;
delete[] this->z;
}
};
void main(){
Test t1(100);
Test *t2 = new Test(100);
//以降でその他処理など
return;
}
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 01:38
by h2so5
中級車 さんが書きました:
ということはt1のフィールドx,y,zが指すヒープ領域は,t1をdeleteせずとも(というかできないが)mainが終わった時点で自動的にデストラクタにより,このプログラムの場合解放されるということですかね・・.
違います。ヒープ領域にある以上は手動で解放する必要があります。
x,y,z自体は自動的に解放されますが、指している先までは解放しません。
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 01:57
by 中級車
Poco さんが書きました:中級車 さんが書きました:
この変数「t1」はスタック領域の変数でしょうか?
そのフィールドである,x,y,zはヒープということになるのでしょうか?
共にYesです。
中級車 さんが書きました:
これをどのように調べたり,又は知ることができるのか分かりません.
VC++を使用する前提で、スタックに確保するオブジェクトであれば、アセンブラレベルでステップ実行し、
メモリの状態を確認すればできるんじゃないかな、と思います。
Poco さんが書きました:中級車 さんが書きました:
この変数「t1」はスタック領域の変数でしょうか?
そのフィールドである,x,y,zはヒープということになるのでしょうか?
共にYesです。
中級車 さんが書きました:
これをどのように調べたり,又は知ることができるのか分かりません.
VC++を使用する前提で、スタックに確保するオブジェクトであれば、アセンブラレベルでステップ実行し、
メモリの状態を確認すればできるんじゃないかな、と思います。
ご回答有難う御座います.参考にさせて頂きます.デバックについては詳しくないのですが,ステップインなどを用いればいいんですかね.
やってみたところ・・・t1はデストラクタが呼ばれてない感じでした.
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 02:34
by 中級車
h2so5 さんが書きました:中級車 さんが書きました:
ということはt1のフィールドx,y,zが指すヒープ領域は,t1をdeleteせずとも(というかできないが)mainが終わった時点で自動的にデストラクタにより,このプログラムの場合解放されるということですかね・・.
違います。ヒープ領域にある以上は手動で解放する必要があります。
x,y,z自体は自動的に解放されますが、指している先までは解放しません。
なるほど...,ちょっといくつか試したのですが,t1のx,y,zの指すヒープはどうしたら解放できるのでしょうか・・・.
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 02:46
by h2so5
中級車 さんが書きました:h2so5 さんが書きました:中級車 さんが書きました:
ということはt1のフィールドx,y,zが指すヒープ領域は,t1をdeleteせずとも(というかできないが)mainが終わった時点で自動的にデストラクタにより,このプログラムの場合解放されるということですかね・・.
違います。ヒープ領域にある以上は手動で解放する必要があります。
x,y,z自体は自動的に解放されますが、指している先までは解放しません。
なるほど...,ちょっといくつか試したのですが,t1のx,y,zの指すヒープはどうしたら解放できるのでしょうか・・・.
回答の仕方で誤解を与えてしまったかもしれませんが、この場合x, y, zの指している先はクラスのデストラクタでdeleteされていますので、
結果的にはmain関数の終了時、t1のデストラクタが呼ばれるときに解放されます。
Re: その変数はスタックかヒープか
Posted: 2013年8月02日(金) 06:20
by 中級車
回答の仕方で誤解を与えてしまったかもしれませんが、この場合x, y, zの指している先はクラスのデストラクタでdeleteされていますので、
結果的にはmain関数の終了時、t1のデストラクタが呼ばれるときに解放されます
ご回答有難う御座いました.討論をしていくなかで理解で深まりとても参考になりました.それなりの理解ができたので,ここで解決とします.