C ++動的メモリ
動的メモリがC ++で実際にどのように機能するかをよく理解することは、優れたC ++プログラマーになるために不可欠です。C ++プログラムのメモリは2つの部分に分かれています-
The stack −関数内で宣言されたすべての変数は、スタックからメモリを消費します。
The heap −これはプログラムの未使用メモリであり、プログラムの実行時にメモリを動的に割り当てるために使用できます。
多くの場合、定義された変数に特定の情報を格納するために必要なメモリの量を事前に認識しておらず、必要なメモリのサイズは実行時に決定できます。
割り当てられたスペースのアドレスを返すC ++の特別な演算子を使用して、特定のタイプの変数のヒープ内で実行時にメモリを割り当てることができます。この演算子はと呼ばれますnew オペレーター。
動的に割り当てられたメモリが不要になった場合は、次を使用できます。 delete 演算子。以前に新しい演算子によって割り当てられたメモリの割り当てを解除します。
新規および削除演算子
使用する一般的な構文は次のとおりです new 任意のデータ型に動的にメモリを割り当てる演算子。
new data-type;
ここに、 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
上記の概念を置き、次の例を作成して、「new」と「delete」がどのように機能するかを示しましょう。
#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!