情報分野を学習中の大学生です。
C言語の動的メモリ利用について質問させて頂きます。
先日、基数ソートを実装している際に、動的メモリを利用しました。
ソートデータ数の都合上(最大10桁100万個)、確保すべきバッファ領域が膨大だったためです。
※実際に必要だったバッファ:buf[0][0] - buf[9][1000000-1]
ここで私が動的メモリを利用した動機は「バッファ領域でかすぎるからメモリ圧迫するし動的メモリのほうがいいかな?」といったものです。
コードを書いているうちに、この認識の正誤と、どういったケースで動的メモリを扱うべきか気になりました。
御回答宜しくお願いします。
No.3ベストアンサー
- 回答日時:
> 「バッファ領域でかすぎるからメモリ圧迫するし動的メモリのほうがいいかな?」
その理由で動的なメモリーの割り当てを利用するというのは、誤りです。
普通、それのことはバッファ領域ではなく、スタックというように思います。バッファという言葉には何かのデータの一時置き場という意味しかないので、スタック上に取るのもヒープ上に取るのも自由です。少量のものはスタックにとり、大量のものはヒープにとるのが普通でしょう。
ただ、ヒープに取るものは必ずしも動的にメモリーを割り当てる必要はありません。例えば、グローバル変数に取れば自動的にヒープに容量が割り当てられます。
たしかに、一般にスタックの伸びしろのほうがヒープよりも少なめになっていますが、必ずしもそれが正しいとはいえません。例えば、Unix系のOSだとlimitなどで簡単にスタックやヒープのサイズを変更できます。もちろん、動的に割り当てられるメモリーもヒープ上に取られますので、そういう使い方も可能ではありますが。
> どういう時に動的なメモリー割り当てを利用するか?
配列と変数と式だけのToyプログラムを書いているうちは特に動的なメモリーの割り当ては必要ないと思います。
実用的なプログラムは普通のユーザーから様々な入力をとり、それを複数の関数で処理します。スタック上に取られている変数だと、その関数を抜けたら開放されてしまうので、複数の関数で処理を行うのが大変困難です。そして、どれだけの容量を確保したらいいかもユーザーが具体的に指示するまでわかりません。例えば、ソートをする場合でも10個のデータをソートするのか10万個のデータをソートするのかで必要なメモリーは大いに違います。ヒープに予め確保しておくと、無駄ですし、想定よりも大きなデータが来た時に処理できません。(ちなみに、普通のOSはデマンドページングをするので、10万個分のメモリーをヒープにとって、10個しか来なくても、実際にメモリーを使う量は微々たるものですが)
また、モジュール化/カプセル化とデータ抽象化を学ぶと動的なメモリーの割り当ての必要性に気づくでしょう。この場合、あなたが書いたライブラリーが呼ばれた時に一度にすべての処理をするのは不可能なので、ライブラリーの利用者の指示に従ってすこしずつ処理を進めますが、その中間状態を保存しておくのにスタックは不向きです。また、その場合、どれだけメモリーを用意したらいいのかわからないので、ライブラリーの利用者が特定の関数を呼び出した時に動的なメモリーの確保を行います。
例えば、ファイルの入出力に使われるfopenは内部で動的なメモリーの確保を行っています。利用者は同時に読み書きするファイルの個数分fopenを呼び出します。そして、ファイルの読み書きをするfscanfやfprintfの実行に必要な様々なデータはその動的に確保されたメモリーに入っています。
複数の人で開発している場合も同じ事です。他の人が自分が書いた部分でどの程度メモリーを必要とするか不明なので、必要な分だけ動的に割り当てるようにします。
mallocなどで動的にメモリーが割り当てられる場合、その領域は重複しないので、確保したコードの専用領域として使えます。一つのプログラムが同時に複数の処理を行うマルチスレッドプログラムでは、一つ一つのスレッド (処理を行う一つ一つの単位) が別々の処理を行います。この時、スレッドに動的に割り当てられたメモリーは御行儀よく使えばそのスレッドからしか読み書きされないので、他のスレッドのことを考えずにプログラムを書けるようになります。
これが、逆に動的に割り当てられたメモリーではなく、グローバル変数になっていると、他のスレッドが変更を加える可能性があるので処理が終わるまでロックを取るなどをする必要があり、面倒くさく、性能にも悪い影響を与えます。
と、説明してきましたが、まとめると次の3つですね。
- 複数の関数が同一のデータを取り扱い、プログラムの動作によって必要となるメモリーの量や種類が多いに変わるとき
- データの抽象化をしたいとき
- マルチスレッドのプログラムを書いていて、グローバル変数を使いたくないとき
No.2
- 回答日時:
JPEG画像をビットマップに変換するような処理を考えます。
デジカメの種類によって画像サイズが異なりますから予め固定的な領域を確保しておくわけにはいきません。最大でこのサイズまでしか扱わないという制限を設けておけば別ですが。お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「ヒープサイズの設定」て何?
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
VB.netでUSBメモリの固有I...
-
mmap()
-
バッチファイルでの実行EXEのメ...
-
「memcpy」と「strcpy」について
-
C,C++プログラムの強制終了時の...
-
CPUやメモリの使用率を調べ...
-
エクセル キャッシュメモリー...
-
エクセルVBA 大容量CSVファイル...
-
エクセルのメモリ使用状況/Appl...
-
ウインドウズのシステムにおけ...
-
PIC 文字 を 数値に 変換
-
ファイルマッピング関数で失敗
-
値のコピーについて
-
動的確保できるメモリ容量
-
Macターミナルで実行中のプログ...
-
3のつく数字と3の倍数のみを表...
-
VBSの処理中一旦処理を止めて再...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
C言語における再帰呼び出しの...
-
メモリ不足
-
「ヒープサイズの設定」て何?
-
動的メモリとexit(C言語)
-
エクセルのメモリ使用状況/Appl...
-
大容量のメモリ確保をスワップ...
-
【C言語】再帰が時間がかかる...
-
バッチファイルでの実行EXEのメ...
-
メモリのセグメント違反の解決...
-
「memcpy」と「strcpy」について
-
ExcelのVBAでメモリ解放できない
-
これて逆じゃないですか?
-
メモリを解放しないとどうなる?
-
ファイルマッピング関数で失敗
-
エクセルVBA 大容量CSVファイル...
-
メモリアロケーション異常の発...
-
エクセル キャッシュメモリー...
-
Apacheでバーチャルホストの最...
おすすめ情報