必要なメモリの確保(アロケート)と解放(デアロケート、リリース)を、プログラムの実行中に行う、メモリ管理の手法のことです。
プログラムが使うすべてのメモリを事前に(静的に)確保しておこうとすると、膨大すぎて現実的でないことも多いですが、一時的にしか使われないメモリや、ある条件下でしか使わないメモリを動的に確保・解放すれば、一度に必要になるメモリの量を抑えることができます。
多くの場合、メモリ領域のうち、ヒープと呼ばれる領域を使って実現されます。プログラムの実行開始時に、OS などがメモリ領域の一部をヒープとして使えるように準備し、その領域内を使いまわす仕組みになっています。OS がない環境でも、静的に使えるメモリ領域の一部分をヒープに見立てて、自力で確保・解放を行うプログラムを書いて実装することがあります。
ヒープから割り当てを得たいときには、確保の要求を出します。このときに必要な大きさを指定します。指定された大きさ(実際には、アラインメントや、ヒープの効率的な管理の都合などで少し多めに取られる)のヒープが割り当てられ、その領域を表す情報(たとえば、メモリアドレス)が返されます。要求された大きさ以上の空き領域が “連続して” しなければならず、空き領域をかき集めてきて、1つの領域と見立てて使うことはできません。
割り当てられたメモリ領域の使用を終えたら解放の処理を行います。解放を行うと、使っていた領域が未使用な状態に戻され、次回以降の確保要求で再び割り当てできるようになります。そのため解放を怠っていると、いつまでもその領域は再利用できない状態が続くことになり、メモリ不足に陥る可能性があります。
確保と解放を繰り返しているうちに、未使用部分がヒープ内で飛び飛びになってしまう現象が起こることがあり、全体としては十分な空き領域があるはずなのに、確保に失敗することがあります(フラグメンテーション)。この現象は、確保と解放の順序や、要求する領域の大きさを工夫することで軽減できる可能性があります。また、ヒープ内を整理しなおすコンパクションによって解消できますが、C言語のように、メモリアドレスを直接保持するポインタの仕組みがある言語では、実現が困難です(整理されると、メモリアドレスが変わってしまうので)。
解放をし忘れて、ヒープ内にいつまでも残り続けるミスや(メモリリーク)、解放済みのメモリにまだデータがあるかのようにアクセスしてしまうなど、注意を払わなければならないことが多く、バグの原因になりやすい手法でもあります。プログラミング言語や処理系によっては、こういった問題をある程度防ぐ仕組みが備わっている場合もあります(ガーベジコレクション、スマートポインタ、例外など)。
C言語では、malloc関数、calloc関数、realloc関数などを使って、メモリ領域の確保を要求できます。解放には free関数を使います。具体的な方法についての解説が、C言語編第35章にあります。
ダイナミックメモリアロケーションによって確保されたメモリ領域は、割付け記憶域期間を持ちます。
C++ では、C言語と同様の方法が使えるほか、new演算子による方法があります。new演算子では、メモリの確保に加えて、オブジェクトの作成が行われます。new演算子で確保された領域の解放(とオブジェクトの破棄)には、delete演算子を使います。具体的な方法についての解説が、C++編【標準ライブラリ】第17章にあります。
また、ダイナミックメモリアロケーションで使用するメモリ領域のことをフリーストアと呼んでいます。これは多くの場合、ヒープのことですが、そうでなくても構わないことになっています。
ダイナミックメモリアロケーションによって確保されたメモリ領域は、動的記憶域期間を持ちます。
標準ライブラリには、解放忘れのミスを防ぐため、スマートポインタと呼ばれるいくつかのクラステンプレートが用意されています(std::unique_ptr、std::shared_ptr など)。
Programming Place Plus のトップページへ
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |