コード領域 全関数の格納領域
データ領域 グローバル変数・インスタンス、静的変数・インスタンスの格納領域
スタック領域 仮引数、戻り値?、ローカル変数・インスタンスの格納領域
ヒープ領域 動的変数・インスタンスの格納領域
メモリの格納領域は上記の様な感じだと思うのですが、インスタンスの格納とはメンバ変数の格納と言う事でしょうか。
そう仮定して書きますが、
・ローカルインスタンスのメンバ変数はスタック領域に格納される。
・静的インスタンスのメンバ変数はデータ領域に格納される。
と言う事で良いのでしょうか。
また、画像等をロードすると関数がハンドルやアドレスを返すので、それを介して処理をすると思いますが、読み込まれた画像等の実体はどこに格納されるのでしょうか。
関数内部で動的にメモリを確保しているのでしょうか。
メモリの格納領域について
Re: メモリの格納領域について
すみません、後半しか答えられませんが・・・
で、問題はそれがどこに確保されるのかということです。
PCに専用のグラフィックボードが搭載されているとき、画像など描画関係のデータはほとんど、グラフィックボード上のメモリに読み込まれます。
(但しそれが足りないときや、あらかじめ使わないよう指定したとき、あるいはそもそもボードが無いときはメインメモリが使われます。)
こういうメモリには普通アクセスすることが出来ないので、DirectXなどのAPIというプラックボックスを介してデータを操作します。
DirectXの場合(あるいは、それを利用しているDXライブラリ)しか知らないのですが、大抵はこんな感じです。
はい。画像のメモリ確保は動的に行われます。そうでなければコード上(あるいはスタティックリンクライブラリ)に画像データが含まれていることになってしまいますから。Fimbul さんが書きました: また、画像等をロードすると関数がハンドルやアドレスを返すので、それを介して処理をすると思いますが、読み込まれた画像等の実体はどこに格納されるのでしょうか。
関数内部で動的にメモリを確保しているのでしょうか。
で、問題はそれがどこに確保されるのかということです。
PCに専用のグラフィックボードが搭載されているとき、画像など描画関係のデータはほとんど、グラフィックボード上のメモリに読み込まれます。
(但しそれが足りないときや、あらかじめ使わないよう指定したとき、あるいはそもそもボードが無いときはメインメモリが使われます。)
こういうメモリには普通アクセスすることが出来ないので、DirectXなどのAPIというプラックボックスを介してデータを操作します。
DirectXの場合(あるいは、それを利用しているDXライブラリ)しか知らないのですが、大抵はこんな感じです。
pop'n music 20 fantasia ポップンクエストPhase MAX Ⅱ ムラクモ/少年は空を辿る【Power Of Nature】
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリの格納領域について
Windows等に環境を限定すれば、そういう認識で合っていると思います。Fimbul さんが書きました:・ローカルインスタンスのメンバ変数はスタック領域に格納される。
・静的インスタンスのメンバ変数はデータ領域に格納される。
使うライブラリにもよりますがOSがメモリを動的確保してハンドルを返す場合もあります。GPU内のメモリ領域に読み込む場合もあります。Fimbul さんが書きました:また、画像等をロードすると関数がハンドルやアドレスを返すので、それを介して処理をすると思いますが、読み込まれた画像等の実体はどこに格納されるのでしょうか。
関数内部で動的にメモリを確保しているのでしょうか。
あるいは自分で用意した動的確保メモリに画像を格納しているものもあります。
ハンドルも内部テーブルの番号だったり、動的リストの構造体アドレスだったり色々考えられます。
ゲーム機となるとさらにメモリが足らないとかOS自体も無いこともあるので各ソフトは工夫してメモリ管理しています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: メモリの格納領域について
インスタンスには仮想関数テーブルが含まれる場合もあるのでメンバ変数だけとは限らないです。
グローバル/ローカルというのはスコープに対して意味を持つ言葉なので、ここでは、静的記憶域期間を持つ~(静的~)、とか、自動記憶域期間を持つ~(自動~)、というほうがふさわしいと思います。
グローバル/ローカルというのはスコープに対して意味を持つ言葉なので、ここでは、静的記憶域期間を持つ~(静的~)、とか、自動記憶域期間を持つ~(自動~)、というほうがふさわしいと思います。
Re: メモリの格納領域について
SUE さんが書きました: PCに専用のグラフィックボードが搭載されているとき、画像など描画関係のデータはほとんど、グラフィックボード上のメモリに読み込まれます。
(但しそれが足りないときや、あらかじめ使わないよう指定したとき、あるいはそもそもボードが無いときはメインメモリが使われます。)
こういうメモリには普通アクセスすることが出来ないので、DirectXなどのAPIというプラックボックスを介してデータを操作します。
適宜都合が良い所に格納されるのですね。softya(ソフト屋) さんが書きました: 使うライブラリにもよりますがOSがメモリを動的確保してハンドルを返す場合もあります。GPU内のメモリ領域に読み込む場合もあります。
あるいは自分で用意した動的確保メモリに画像を格納しているものもあります。
ハンドルも内部テーブルの番号だったり、動的リストの構造体アドレスだったり色々考えられます。
ゲーム機となるとさらにメモリが足らないとかOS自体も無いこともあるので各ソフトは工夫してメモリ管理しています。
そうじゃない環境があるとは。softya(ソフト屋) さんが書きました: Windows等に環境を限定すれば、そういう認識で合っていると思います。
仮想関数テーブルを知らなかったので調べました。ISLe さんが書きました: インスタンスには仮想関数テーブルが含まれる場合もあるのでメンバ変数だけとは限らないです。
仮想関数を持つとサイズが大きくなるんですね。
C++編(言語解説) 第9章 オーバーライド
http://www.geocities.jp/ky_webid/cpp/language/009.html
確かにそうですね。ISLe さんが書きました: グローバル/ローカルというのはスコープに対して意味を持つ言葉なので、ここでは、静的記憶域期間を持つ~(静的~)、とか、自動記憶域期間を持つ~(自動~)、というほうがふさわしいと思います。
自動~を全く忘れていました。
追加の質問をさせてください。
「C++の場合、配列を使うならvectorを使え」等と聞きました。
例えば、静的な配列を確保しておき、それにリソースのハンドルやアドレスを格納するとします。
そして、そのリソースが必要無くなれば解放して無駄なメモリの消費を無くせます。
しかし、リソースのハンドルやアドレスを格納していた配列自体は静的変数なのでプロセス中残り続けます。
一方、静的なvectorインスタンスを生成すれば、上記と同じ事をしてもリソースのハンドルやアドレスを格納している配列は動的なのでプロセス中に解放できます。
ですが、今度はvectorインスタンスが静的なのでプロセス中残り続けます。
ならば、vectorインスタンスを動的に生成して、そのアドレスを保持するポインタを静的にすれば、リソースが不要になりメモリを解放した後に残る物は、vectorクラス型へのポインタだけになります。
何が言いたいのかと言いますと、「C++の場合、配列を使うならvectorを使え」の意味は、動的配列の管理が楽であり、無駄なメモリ消費をなくせるからなのでしょうか。
そうだとすると最後のvectorインスタンスを動的に生成する方法が一番良いと思うのですが、何かやり過ぎな感じもします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリの格納領域について
vectorを使うメリットは動的にサイズを拡張してくれることもメリットながら、添字範囲外のガードがされている事などが大きなポイントだと思います。Fimbul さんが書きました: 追加の質問をさせてください。
「C++の場合、配列を使うならvectorを使え」等と聞きました。
例えば、静的な配列を確保しておき、それにリソースのハンドルやアドレスを格納するとします。
そして、そのリソースが必要無くなれば解放して無駄なメモリの消費を無くせます。
しかし、リソースのハンドルやアドレスを格納していた配列自体は静的変数なのでプロセス中残り続けます。
一方、静的なvectorインスタンスを生成すれば、上記と同じ事をしてもリソースのハンドルやアドレスを格納している配列は動的なのでプロセス中に解放できます。
ですが、今度はvectorインスタンスが静的なのでプロセス中残り続けます。
ならば、vectorインスタンスを動的に生成して、そのアドレスを保持するポインタを静的にすれば、リソースが不要になりメモリを解放した後に残る物は、vectorクラス型へのポインタだけになります。
何が言いたいのかと言いますと、「C++の場合、配列を使うならvectorを使え」の意味は、動的配列の管理が楽であり、無駄なメモリ消費をなくせるからなのでしょうか。
そうだとすると最後のvectorインスタンスを動的に生成する方法が一番良いと思うのですが、何かやり過ぎな感じもします。
つまりポインタ問題や添字問題をガード・隠蔽できる安全な使い方と言えるでしょう。
それに対して、vectorインスタンスを動的に生成することで十分なメリットがあるほどメモリ節約になるのでしょうか?安全性を犠牲にするほどのメリットがあるのか?それが問題ですね。
一般にvectorを選ぶのか、配列をnewで確保するのか、あるはリスト構造なのかケースバイケースです。
メリット(速度・メント性・安定性)とデメリット(メモリ増加・低速化・不安定性)などを測りにかけて適材適所で選択します。
全部vectorで良いなんて物はありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: メモリの格納領域について
添え字範囲外のガードと言うのはatの事でしょうか。softya(ソフト屋) さんが書きました: vectorを使うメリットは動的にサイズを拡張してくれることもメリットながら、添字範囲外のガードがされている事などが大きなポイントだと思います。
つまりポインタ問題や添字問題をガード・隠蔽できる安全な使い方と言えるでしょう。
atは非常に処理に時間がかかると聞いたので[]でアクセスしていました。
これがもっとも気になっていた事なのですが、メモリの感覚が乏しく、どの程度からメモリ消費が大きいと言うのか分からないのです・・・。softya(ソフト屋) さんが書きました: それに対して、vectorインスタンスを動的に生成することで十分なメリットがあるほどメモリ節約になるのでしょうか?安全性を犠牲にするほどのメリットがあるのか?それが問題ですね。
さすがに中小規模のプログラムで 1 [GB] 使っていれば使い過ぎだと言う事は分かるのですが。
メント性とはメンテ(メンテナンス)性の事でしょうか。softya(ソフト屋) さんが書きました: 一般にvectorを選ぶのか、配列をnewで確保するのか、あるはリスト構造なのかケースバイケースです。
メリット(速度・メント性・安定性)とデメリット(メモリ増加・低速化・不安定性)などを測りにかけて適材適所で選択します。
全部vectorで良いなんて物はありません。
そうだとして、vector new[] listの場合、メンテ性、安定性、とは具体的にどういう事なのでしょう。
また、速度 : (遅) list vector new[] (速) でよろしいのでしょうか。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: メモリの格納領域について
そうですねatの事です。聞いた話だけでなく自分でatがどのぐらい遅いか実験してみることも大事ですよ。Fimbul さんが書きました:添え字範囲外のガードと言うのはatの事でしょうか。softya(ソフト屋) さんが書きました: vectorを使うメリットは動的にサイズを拡張してくれることもメリットながら、添字範囲外のガードがされている事などが大きなポイントだと思います。
つまりポインタ問題や添字問題をガード・隠蔽できる安全な使い方と言えるでしょう。
atは非常に処理に時間がかかると聞いたので[]でアクセスしていました。
これも同じですが実験して自分で実感を掴むべきです。Fimbul さんが書きました:これがもっとも気になっていた事なのですが、メモリの感覚が乏しく、どの程度からメモリ消費が大きいと言うのか分からないのです・・・。softya(ソフト屋) さんが書きました: それに対して、vectorインスタンスを動的に生成することで十分なメリットがあるほどメモリ節約になるのでしょうか?安全性を犠牲にするほどのメリットがあるのか?それが問題ですね。
さすがに中小規模のプログラムで 1 [GB] 使っていれば使い過ぎだと言う事は分かるのですが。
32bit環境ならポインタは確かに4バイトでvectorインスタンスより小さいですが、vectorインスタンスが沢山プログラム中で度々生成と消滅しな限りさほど意味はないと思います。
vectorインスタンスが何バイトか調べて見ましたか?1つで困るほど大きなサイズでしょうか?じゃあ100個だったら?
プログラム内で使う数は予想できますよね。だったら予備計算できるはずです。
で、一般的なアプリやゲームプログラムがメモリをどのぐらい消費しているかはタスクマネージャで見てみましょう。
失礼しました。メンテ性の打ち間違いです。Fimbul さんが書きました:メント性とはメンテ(メンテナンス)性の事でしょうか。softya(ソフト屋) さんが書きました: 一般にvectorを選ぶのか、配列をnewで確保するのか、あるはリスト構造なのかケースバイケースです。
メリット(速度・メント性・安定性)とデメリット(メモリ増加・低速化・不安定性)などを測りにかけて適材適所で選択します。
全部vectorで良いなんて物はありません。
そうだとして、vector new[] listの場合、メンテ性、安定性、とは具体的にどういう事なのでしょう。
また、速度 : (遅) list vector new[] (速) でよろしいのでしょうか。
vectorやlistを使ったほうが安定性やメンテ性で有利ですが速度は犠牲になります。それにサイズ可変の配列でもプログラム起動中に何度もサイズが変わらなくて添字上限下限をガード出来るならnew[]で生成したほうがシンプルでメンテ性が高いかも知れません。
速度に関しては、シーケンシャルアクセスとランダムアクセスでlistとvectorでは速度優位が変わります。なのでケースバイケースです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: メモリの格納領域について
「C++なら配列よりvector」主義の様なものがあるのかと思い、すっきりしました。softya(ソフト屋) さんが書きました: vectorやlistを使ったほうが安定性やメンテ性で有利ですが速度は犠牲になります。それにサイズ可変の配列でもプログラム起動中に何度もサイズが変わらなくて添字上限下限をガード出来るならnew[]で生成したほうがシンプルでメンテ性が高いかも知れません。
速度に関しては、シーケンシャルアクセスとランダムアクセスでlistとvectorでは速度優位が変わります。なのでケースバイケースです。
やはり、ケースバイケースが大切なんですね。
SUEさん、softyaさん、ISLeさん、返信ありがとうございました。