C++ 動的メモリ
C++ で動的メモリが実際にどのように機能するかを十分に理解することは、優れた C++ プログラマーになるために不可欠です。 C++ プログラムのメモリは 2 つの部分に分かれています −
- <リ>
スタック − 関数内で宣言されたすべての変数は、スタックからメモリを占有します。
<リ>ヒープ − これはプログラムの未使用メモリであり、プログラムの実行時にメモリを動的に割り当てるために使用できます。
多くの場合、定義済みの変数に特定の情報を格納するために必要なメモリの量を事前に認識していません。また、必要なメモリのサイズは実行時に決定できます。
割り当てられたスペースのアドレスを返す C++ の特別な演算子を使用して、特定の型の変数のヒープ内で実行時にメモリを割り当てることができます。この演算子は new と呼ばれます
動的に割り当てられたメモリが不要になった場合は、delete を使用できます new 演算子によって以前に割り当てられたメモリの割り当てを解除します。
new および delete オペレータ
new を使用する一般的な構文は次のとおりです。 演算子を使用して、任意のデータ型にメモリを動的に割り当てます。
new data-type;
ここで、データ型 配列を含む任意の組み込みデータ型、またはクラスまたは構造体を含む任意のユーザー定義データ型にすることができます。組み込みのデータ型から始めましょう。たとえば、double 型へのポインタを定義して、実行時にメモリを割り当てるように要求できます。 new を使用してこれを行うことができます 次のステートメントを含む演算子 −
double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable
フリーストアが使い果たされた場合、メモリが正常に割り当てられなかった可能性があります。したがって、新しい演算子が NULL ポインターを返しているかどうかを確認し、以下のように適切なアクションを実行することをお勧めします −
double* pvalue = NULL; if( !(pvalue = new double )) { cout << "Error: out of memory." <<endl; exit(1); }
malloc() C の関数は C++ にも存在しますが、malloc() 関数の使用を避けることをお勧めします。 malloc() に対する new の主な利点は、new がメモリを割り当てるだけでなく、C++ の主要な目的であるオブジェクトを構築することです。
いつでも、動的に割り当てられた変数が不要になったと感じたら、次のように「削除」演算子を使用して、フリーストアで占有しているメモリを解放できます-
delete pvalue; // Release memory pointed to by pvalue
上記の概念を入れて、次の例を作成して、「新規」と「削除」がどのように機能するかを示しましょう −
ライブデモ#include <iostream> using namespace std; int main () { double* pvalue = NULL; // Pointer initialized with null pvalue = new double; // Request memory for the variable *pvalue = 29494.99; // Store value at allocated address cout << "Value of pvalue : " << *pvalue << endl; delete pvalue; // free up the memory. return 0; }
上記のコードをコンパイルして実行すると、次の結果が生成されます −
Value of pvalue : 29495
配列の動的メモリ割り当て
文字の配列、つまり 20 文字の文字列にメモリを割り当てたいとします。上で使用したのと同じ構文を使用して、以下に示すようにメモリを動的に割り当てることができます。
char* pvalue = NULL; // Pointer initialized with null pvalue = new char[20]; // Request memory for the variable
作成したばかりの配列を削除するには、ステートメントは次のようになります −
delete [] pvalue; // Delete array pointed to by pvalue
new 演算子の同様の一般的な構文に従って、次のように多次元配列に割り当てることができます −
double** pvalue = NULL; // Pointer initialized with null pvalue = new double [3][4]; // Allocate memory for a 3x4 array
ただし、多次元配列のメモリを解放する構文は上記と同じままです −
delete [] pvalue; // Delete array pointed to by pvalue
オブジェクトの動的メモリ割り当て
オブジェクトは単純なデータ型と同じです。たとえば、概念を明確にするためにオブジェクトの配列を使用する次のコードを考えてみましょう -
ライブデモ#include <iostream> using namespace std; class Box { public: Box() { cout << "Constructor called!" <<endl; } ~Box() { cout << "Destructor called!" <<endl; } }; int main() { Box* myBoxArray = new Box[4]; delete [] myBoxArray; // Delete array return 0; }
4 つの Box オブジェクトの配列を割り当てると、Simple コンストラクターが 4 回呼び出され、同様にこれらのオブジェクトを削除するときに、デストラクタも同じ回数呼び出されます。
上記のコードをコンパイルして実行すると、次の結果が生成されます −
Constructor called! Constructor called! Constructor called! Constructor called! Destructor called! Destructor called! Destructor called! Destructor called!
C言語