OSは(プログラムが終了した後)それを回復するだけですよね?では、優れたプログラミングスタイル以外の用途は何ですか?それとも私が誤解していることがありますか?どちらも実行時に変更でき、どちらもプログラムの実行後に終了するため、「自動」割り当てとの違いは何ですか。
8 に答える
アプリケーションが大量のデータを処理している場合、ヒープスペースを節約するために解放する必要があります。そうしないと、いくつかの悪いことが起こる可能性があります。
- OSはメモリの割り当てを停止します(クラッシュ)
- OSはデータのディスクへのスワップを開始します(スラッシング)
- 他のアプリケーションでは、データを配置するスペースが少なくなります
アプリケーションの終了時にOSが割り当てたすべてのスペースを収集するという事実は、堅実なアプリケーションを作成するためにこれに依存する必要があるという意味ではありません。これは、貧弱なプログラミングを最適化するためにコンパイラに依存しようとするようなものです。メモリ管理は、優れたパフォーマンス、スケーラビリティ、および信頼性にとって非常に重要です。
他の人が述べたように、malloc
自動変数がスタック上に作成されている間、ヒープにスペースを割り当てます。両方の用途がありますが、実際には非常に異なります。ヒープスペースはOSによって割り当ておよび管理される必要があり、動的にさまざまなサイズのデータを格納できます。
自動変数は、それが定義されているスコープを終了するとすぐに破棄されます(そしてそのメモリは再利用可能になります)。ほとんどの変数では、プログラムの終了よりもはるかに早いです。
そうmalloc
しないとfree
、プログラムが終了するまでメモリを再利用できません。それでも、OSが非常に少ない一部のシステムでは。
そうです、自動変数とリークされたメモリ割り当てには大きな違いがあります。割り当てを十分な回数リークする関数を呼び出すと、メモリが不足します。自動変数を含む関数を何度でも呼び出すと、メモリは再利用可能になります。
C / C ++では、「自動」変数がスタックに割り当てられます。それらは関数の出口ですぐに破棄されます。これは自動的に行われます。このために何も書く必要はありません。
ヒープ割り当て(への呼び出しの結果malloc
)は、明示的に(への呼び出しを使用してfree
)解放されるか、プロセスの終了時にクリーンアップされます。
おそらく1回か2回使用される小さなプログラムを作成している場合は、ヒープ割り当てを解放しなくてもかまいません。これは良くありませんが、許容できます。
中規模または大規模なプロジェクトを作成している場合、またはコードを他のプロジェクトに含めることを計画している場合は、すべてのヒープ割り当てを確実に解放する必要があります。これを行わないと、大きな問題が発生します。ヒープメモリは無限ではありません。プログラムはそれをすべて使用することができます。少量のメモリを割り当てたとしても、OSに不必要なプレッシャーがかかり、スワッピングなどが発生します。
結論:割り当てを解放することは、単なるスタイルや良い習慣以上のものです。
それは良いプログラミングスタイルであり、それ以上のものです。重要なプログラムで適切なメモリ管理を行わないと、最終的にはプログラムのユーザビリティに影響を及ぼします。確かに、OSは、プログラムの終了後に割り当て/使用したリソースを再利用できますが、プログラムの実行中の負担や潜在的な問題を軽減することはできません。
この質問を投稿するために使用したWebブラウザについて考えてみます。ブラウザがメモリ管理を必要とする言語で記述されていて、コードが適切に実行しなかった場合、気付くまでにどれくらいかかると思いますか。それはあなたのすべての記憶を食い尽くしていると?ブラウザはいつまで使用できると思いますか?ここで、ユーザーがブラウザを長時間開いたままにしておくことがよくあることを考えてみてください。適切なメモリ管理がないと、ページを数回ロードするとブラウザが使用できなくなります。
free()を使用せずにマクロを1000回呼び出すと、コンパイラまたはシステムが1000の異なるアドレスを割り当てますが、各mallocの後にfree()を使用すると、毎回1つのメモリアドレスのみが割り当てられます。したがって、メモリリーク、バスエラー、メモリの範囲外、クラッシュの可能性は最小限に抑えられます。free()を使用しても安全です。
プログラムがすぐに終了せず、メモリを解放しない場合は、プログラムを無駄にすることになります。最終的にメモリが不足するか、ディスクへのスワップを開始します(これは低速であり、無制限ではありません)。
自動変数はスタック上にあり、そのサイズはコンパイル時に認識されている必要があります。たとえば、サイズに合わないデータを保存する必要がある場合は、ユーザーがオブジェクトを追加および削除するバイナリツリーを維持します。スタックサイズが制限されている可能性があることに加えて(ターゲットによって異なります)、たとえば、Linuxカーネルのスタックは通常4k〜8kです。また、パフォーマンスに影響を与える命令キャッシュを破棄します。
はい、malloc()の後にfree()を絶対に使用する必要があります(完了したらファイルやその他のリソースを閉じます)。OSが実行後にそれを回復するのは事実ですが、長時間実行されているプロセスはその方法でメモリをリークします。プログラムが単一のメソッドを実行するメインメソッドのように単純である場合、それは信じられないほどずさんなものですが、おそらく大したことではありません。ある日、1秒以上実行される重要なプログラムを作成したいと思うかもしれないので、Cでメモリを適切に管理する習慣を身につける必要があります。事前にそれを行う方法を学ばなければ、次のようになります。メモリリークに対処するための大きな頭痛の種。