はじめに
42Tokyoの生徒です。ヒープ領域、スタック領域という用語があまりわかっていなかったので、調べてみました。
メモリ領域の種類
主に4つの領域に分けられるようです。
・ヒープ領域
・スタック領域
・静的データ領域
・テキスト領域
※本記事は、ヒープ領域、スタック領域を中心に記載します。
ヒープ領域とは
・プログラム実行中に動的に確保・解放できる領域。
・プログラムの実行中に大きいサイズのメモリや柔軟にメモリを管理したい場合に利用する。
・malloc関数などを用いて、必要な時に必要なサイズのメモリを確保できる。
・確保したメモリはfree関数で明示的に解放する必要がある。
スタック領域とは
・関数呼び出し時に自動的に確保され、関数呼び出しが終わると自動的に解放される領域。
・関数内のローカルなデータの格納などに用いられる。
・後入れ先出し(LIFO)方式で管理される
静的データ領域とは
・プログラムの開始時に確保され、プログラム終了まで解放されない領域。
・グローバル変数や静的変数の格納などに用いられる。
テキスト領域とは
・プログラムの機械語コードが格納される領域。
・プログラムの実行中に変更されることはない。
(素人ながらの疑問)メモリの解放を忘れるので全てスタック領域出メモリ操作すればいいのでは?
ヒープ領域を使ったほうがいい場合もあるらしい。
①データサイズの制限:
一般的にヒープ領域よりもサイズが小さく、固定されているので、大きなデータや、実行時にサイズが変動するデータを扱う場合、スタックオーバーフローが発生する可能性が高くなる。
②動的なメモリ管理の難しさ:
ヒープ領域は、malloc関数などで動的にメモリを確保できるため、プログラムの実行中に柔軟にメモリを管理できる。スタック領域のみを使用する場合、事前に必要なメモリサイズを正確に予測する必要があり、動的なメモリ管理が難しくなる。
メモリ管理に関するその他用語
・メモリリーク
ヒープ領域でメモリを解放し忘れることによって発生する問題。
・スタックオーバーフロー
スタック領域が不足して発生するエラー。
・メモリ断片化:
ヒープ領域が小さな空き領域に分割されてしまい、大きなメモリを確保できなくなる現象。
・メモリ破壊:
解放済みのメモリにアクセスしたり、確保されたメモリ領域の外にアクセスしたりすると、予期せぬ動作やクラッシュを引き起こす。
メモリの解放を忘れていないかチェックするには
以下のコードで確認可能らしい。ただし、Macではvalgridがサポートされていないらしいです(涙
valgrind --tool=memcheck ./my_program
memcheckの部分を変えるとメモリリーク以外にもさまざまな確認が可能。
・memcheck: メモリリーク、メモリ破損、未定義の動作などを検出する。
・cachegrind: キャッシュミスの検出とプロファイリングを行う。
・callgrind: カールグラフを作成し、プログラムの呼び出し関係を可視化する。
・helgrind: マルチスレッドプログラムのスレッドエラーを検出する。
・massif: ヒーププロファイラで、ヒープメモリ使用量を分析する。
※Macの場合や上記実行できない場合は、以下記事を参考にで確認可能でした。