メモリモデル
C++標準にはメモリモデルがあります。これは、一般的な方法でコンピュータシステムのメモリをモデル化しようとします。この規格では、バイトはメモリモデルのストレージユニットであり、メモリはバイトで構成されていると定義されています(§1.7)。
C++メモリモデルの基本的なストレージユニットはバイトです。[...] C ++プログラムで使用可能なメモリは、連続するバイトの1つ以上のシーケンスで構成されます。
オブジェクトモデル
標準は常にオブジェクトモデルを提供します。これは、オブジェクトがストレージの領域であることを指定します(したがって、オブジェクトはバイトで構成され、メモリに常駐します)(§1.8):
C ++プログラムの構成要素は、オブジェクトを作成、破棄、参照、アクセス、および操作します。オブジェクトはストレージの領域です。
さあ、行きます。メモリはオブジェクトが保存される場所です。オブジェクトをメモリに格納するには、必要なストレージ領域を割り当てる必要があります。
割り当ておよび割り当て解除機能
この標準は、暗黙的に宣言された2つのグローバルスコープ割り当て関数を提供します。
void* operator new(std::size_t);
void* operator new[](std::size_t);
これらがどのように実装されるかは、標準の関心事ではありません。重要なのは、渡された引数(§3.7.4.1)に対応するバイト数でストレージのある領域へのポインタを返す必要があるということです。
割り当て機能は、要求された量のストレージを割り当てようとします。成功した場合、バイト単位の長さが少なくとも要求されたサイズと同じ大きさであるストレージのブロックの開始アドレスを返します。割り当て機能からの復帰時に、割り当てられたストレージの内容に制約はありません。
また、対応する2つの割り当て解除関数も定義します。
void operator delete(void*);
void operator delete[](void*);
以前に割り当てられたストレージの割り当てを解除するために定義されているもの(§3.7.4.2):
標準ライブラリの割り当て解除関数に指定された引数がnullポインタ値(4.10)ではないポインタである場合、割り当て解除関数は、ポインタによって参照されるストレージの割り当てを解除し、割り当て解除されたストレージの任意の部分を参照するすべてのポインタを無効にします。 。
new
とdelete
通常、割り当ておよび割り当て解除機能は、初期化されていないメモリしか提供しないため、直接使用する必要はありません。代わりに、C ++では、オブジェクトを動的に割り当てるためにnew
とを使用する必要があります。new-expressiondelete
は、上記の割り当て関数の1つを使用して、要求されたタイプのストレージを取得し、そのオブジェクトを何らかの方法で初期化します。たとえば、オブジェクトにスペースを割り当ててから、それを0に初期化します。§5.3.4を参照してください。new int()
int
new-expressionは、割り当て関数(3.7.4.1)を呼び出すことにより、オブジェクトのストレージを取得します。
[...]
タイプTのオブジェクトを作成するnew-expressionは、そのオブジェクトを初期化します[ ... ]
反対方向にdelete
、オブジェクトのデストラクタ(存在する場合)を呼び出してから、ストレージの割り当てを解除します(§5.3.5)。
delete-expressionのオペランドの値がnullポインター値でない場合、delete-expressionは、削除されるオブジェクトまたは配列の要素のデストラクタ(存在する場合)を呼び出します。
[...]
delete-expressionのオペランドの値がnullポインター値でない場合、delete-expressionは割り当て解除関数(3.7.4.2)を呼び出します。
その他の割り当て
ただし、ストレージの割り当てまたは割り当て解除の方法はこれらだけではありません。言語の多くの構成要素は、暗黙的にストレージの割り当てを必要とします。たとえば、のようなオブジェクト定義を与えるには、int a;
ストレージも必要です(§7)。
定義により、適切な量のストレージが予約され、適切な初期化(8.5)が実行されます。
C標準ライブラリ:malloc
およびfree
さらに、<cstdlib>
ヘッダーは、および関数stdlib.h
を含むC標準ライブラリのコンテンツを取り込みます。また、C ++標準で定義されている割り当ておよび割り当て解除関数と同様に、メモリの割り当ておよび割り当て解除もC標準で定義されています。(C99§7.20.3.3)の定義は次のとおりです。malloc
free
malloc
void *malloc(size_t size);
説明
このmalloc
関数は、サイズが指定されsize
、値が不定であるオブジェクトにスペースを割り当てます。
戻り値
このmalloc
関数は、nullポインターまたは割り当てられたスペースへのポインターのいずれかを返します。
そしてfree
(C99§7.20.3.2)の定義:
void free(void *ptr);
説明
このfree
関数により、が指すスペースのptr
割り当てが解除されます。つまり、追加の割り当てに使用できるようになります。ptr
がnullポインタの場合、アクションは発生しません。calloc
それ以外の場合、引数が、、、malloc
またはrealloc
関数によって以前に返されたポインターと一致しない場合、またはスペースがfree
またはへの呼び出しによって割り当て解除された場合realloc
、動作は未定義です。
malloc
ただし、free
C++で使用する良い言い訳はありません。前に説明したように、C++には独自の選択肢があります。
質問への回答
だからあなたの質問に直接答えるには:
割り当てられている「メモリ」はどこにありますか?
C++標準は気にしません。それは単に、プログラムがバイトで構成されているメモリを持っていることを示しています。このメモリは割り当てることができます。
この「記憶」とは?配列内のスペース?または、他の何か?
標準に関する限り、メモリは単なるバイトシーケンスです。標準は典型的なコンピュータシステムをモデル化しようとするだけなので、これは意図的に非常に一般的です。ほとんどの場合、これはコンピュータのRAMのモデルと考えることができます。
この「メモリ」が割り当てられると、正確にはどうなりますか?
メモリを割り当てると、プログラムで使用できるストレージの一部の領域が作成されます。オブジェクトは割り当てられたメモリで初期化されます。知っておく必要があるのは、メモリを割り当てることができるということだけです。プロセスへの物理メモリの実際の割り当ては、オペレーティングシステムによって行われる傾向があります。
メモリの割り当てが解除されると、正確にはどうなりますか?
以前に割り当てられたメモリの割り当てを解除すると、そのメモリはプログラムで使用できなくなります。割り当て解除されたストレージになります。
また、誰かがこれらのC++行でmallocが行うことを答えることができれば本当に役に立ちます。
char* x;
x = (char*) malloc (8);
ここでmalloc
は、単に8バイトのメモリを割り当てています。返されるポインタはにキャストされ、char*
に格納されx
ます。