C言語では、変数のメモリはスタック(stack)またはヒープ(heap)に割り当てられます。
malloc、calloc、reallocを通じて動的にメモリを割り当て、freeを使って手動で解放します。メモリの量はシステムの能力によって制限されますが、アクセスは遅く、手動で解放を管理する必要があります。スタックを使用するタイミング:
ヒープを使用するタイミング:
// スタックに int arr[10]; // ヒープに int* parr = malloc(sizeof(int) * 10); // メモリを解放するのを忘れずに free(parr);
質問: mallocを通じて割り当てた配列に対してfreeを呼び出さなかったらどうなりますか?
回答: メモリリーク(memory leak)が発生します。動的に割り当てられたメモリは自動的に解放されず、時間が経つにつれてアプリケーションやシステム全体のメモリが枯渇する可能性があります。
void leak() { int* leakArr = malloc(100 * sizeof(int)); // free(leakArr)の呼び出しがないため、メモリが失われます }
逸話
あるプロジェクトでは、プログラマがセッションを記述する構造体のメモリをmallocで割り当てましたが、セッションの作業が終わった後にfreeを呼ばなかったため、数日間メモリが失われ、サーバーはメモリ不足のエラーで「落ち」ました。この問題はValgrindでプロファイリングを行い、すべての欠落しているfreeを修正するまで解決されませんでした。
逸話
ある開発者が一時計算のためにスタックに大きな配列(最大10MB)を割り当てました。スタックサイズが小さいサーバーでは、これがアプリケーションをスタックオーバーフローエラーでクラッシュさせました。分析の結果、バッファをヒープに移す必要がありました。
逸話
ある開発者がスタックに長い文字列を保持することを決定しましたが、文字列のサイズはユーザーによって主観的に設定されました。非常に長い文字列を入力すると、アプリケーションがメモリアクセスエラーで落ちました。その結果、入力データを長さをチェックしながらヒープに移す決定が下されました。