ProgrammingC開発者

C言語におけるスタックとヒープの違いと、それぞれのメモリタイプをいつ使うべきかを説明してください。

Hintsage AIアシスタントで面接を突破

回答。

C言語では、変数のメモリはスタック(stack)またはヒープ(heap)に割り当てられます。

  • スタック — 関数に入ると自動的にメモリを割り当て、出ると解放されます。高速ですが、メモリの量はスタックのサイズ(通常は数MB)に制限されます。
  • ヒープmalloccallocreallocを通じて動的にメモリを割り当て、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)を割り当てました。スタックサイズが小さいサーバーでは、これがアプリケーションをスタックオーバーフローエラーでクラッシュさせました。分析の結果、バッファをヒープに移す必要がありました。


逸話

ある開発者がスタックに長い文字列を保持することを決定しましたが、文字列のサイズはユーザーによって主観的に設定されました。非常に長い文字列を入力すると、アプリケーションがメモリアクセスエラーで落ちました。その結果、入力データを長さをチェックしながらヒープに移す決定が下されました。