フレームとヒープへのメモリ割り当てについて

[戻る]
さおり 2002/05/23(木) 08:08:47
こんにちは。いつも参考にさせてもらっております。
初歩的と思いますが、わからないことがあるので教えて下さい。

変数やオブジェクトなどを定義する際に、
普通に?定義する場合(char myChar[256])と
new演算子(char* myChar = new char[256])
を使用する場合があるようです。

この違いは、フレームに割り当てるかヒープ領域に割り当てるかの違いというふうに
ヘルプからは読み取ったのですが、フレームとヒープというのはいったいどのような
ものなのでしょうか。
また、これらはどのように使い分けていけば良いのでしょうか?

最後に、変数が破棄される時期と言うのは、普通の定義の場合スコープから出た時、
new演算子を使った場合は、deleteするまでは破棄されない。
という認識で良いのでしょうか?

宜しくお願いします。

Bun 2002/05/23(木) 08:27:33
>フレームに割り当てるかヒープ領域に割り当てるかの違いというふうに

フレームというのはおそらくスタックのことですね。
図のついた説明がありました。じっくり読んでみてください。

http://www2s.biglobe.ne.jp/~gkimoto/j/hello/topics/ch07_parameters.html

>new演算子を使った場合は、deleteするまでは破棄されない。
>という認識で良いのでしょうか?

良いと思います。

PAI 2002/05/23(木) 09:15:28
重箱の隅をつつきますと、あと、static 領域、global 領域があります。

スタック(スタックフレーム)
    auto 変数(非static ローカル変数)がおかれる。
    関数スコープと同期して上下する。
    確保するサイズは静的に(コンパイル時に)定まっている必要がある。
    
    
ヒープ
    new, malloc 等で動的に確保される。
    delete, free よって開放しなければならない。
    一般的には、
    ・実行時になるまでサイズのわからない、あるいは実行時にサイズが変化するデー
タ、
    ・関数のスコープとは違う永続的なデータ、
    を格納するために使用される。
    

static 領域
    各種スタティック変数がおかれる。プログラムの一生を通して大きさは不変。
    ・サイズがあらかじめわかっておりプログラム全体を通して有効であってほしい変
数、
    ・二つ以上存在してほしくないオブジェクト、
    ・関数内で以前の状態を覚えておくための変数、
    等に使用される。


global 領域
    グローバル変数がおかれる。static 領域と同じく大きさは不変。
    静的ですべてのスコープから可視であるべき変数に使用される。
    (弊害が大きいため、あまり汎用的には使用しない)
        

使い分け、という点ですが、基本的には変数は auto 変数、
つまりスタック上の変数を使用して、それでうまくいかないとき
ヒープの使用を考える、ぐらいだと思います。

さおり 2002/05/23(木) 12:26:32
あるオブジェクトかクラスを、CObject myOBject;と言う風に
フレームに割り当てておいて、そのクラスの中でmallocのような
ヒープを使う関数を使用した場合や、その逆の場合は
どのようになるのでしょうか?

何らかのオブジェクトの中であっても外であっても、
ヒープを使用した場合は自分で開放し、フレームに割り当てたものは
自動で開放されると考えれば良いのでしょうか?

上の例だと、「オブジェクト自体は自動で開放されるが、
その中でmallocで割り当てた分は開放されないので、
オブジェクトの中でFree等の記述をきちんとする必要がある。」
ということでしょうか?

Bun 2002/05/23(木) 12:34:55
>何らかのオブジェクトの中であっても外であっても、
>ヒープを使用した場合は自分で開放し、フレームに割り当てたものは
>自動で開放されると考えれば良いのでしょうか?

フレームがスタックを指すのなら、そう考えて良いと思います。

>上の例だと、「オブジェクト自体は自動で開放されるが、
>その中でmallocで割り当てた分は開放されないので、
>オブジェクトの中でFree等の記述をきちんとする必要がある。」
>ということでしょうか?

そういうことです。

PAI 2002/05/23(木) 12:40:35
>上の例だと、「オブジェクト自体は自動で開放されるが、
>その中でmallocで割り当てた分は開放されないので、
>オブジェクトの中でFree等の記述をきちんとする必要がある。」

完璧です。
// そういったことをデストラクタで行うといいかんじです。

で、逆の例ですが、あるオブジェクトのメンバ関数内で作った
ローカル変数はオブジェクトの「中」にはありません。
ローカル変数は実行コンテキストが持つスタック領域に取られます。
スタックは関数を抜けるとポップし、そこにあったものは破棄されます。

// どうでもいいことですがJavaをやってるとこの辺あいまいになってしまいますよね。
// 上の文見づらくなっちゃってますね、すみません。

こんの 2002/05/23(木) 18:57:44
[[解決]]
大変よくわかりました。
Bunさん、PAIさん丁寧なレスありがとうございます。
まだちゃんとしたプログラム一回も作ってないので
早く作りたいです。

わからないことまだいっぱいあると思うので
もしよかったらまた教えてください。

どうもありがとうございました。

古いスレッドには追加発言できません。