動的メモリの割り当て
new と delete
これまでもちらほらと動的メモリの割り当てに関する話が出てきました
クラスのメンバで、動的に割り当てたメモリへのポインタがあるとうんたらと言う話です
しかし、具体的にまだ動的メモリの割り当ての話をしていませんでした
おそらく、動的メモリの割り当てと聞くと malloc() 関数を思い出すでしょう
C++はC言語を用いることができるので、当然問題はありません
が、C++で malloc() を使うことはあまり推奨されません
C++ では独自のメモリ割り当て演算子 new 演算子 があるからです
new type;
type には、割り当てるデータ型を指定します。クラス型も当然OKです
new 演算子は malloc() と違って、割り当てるべきバイト数を自動で計算してくれます
sizeof() 演算子を用いてこちらから指定する必要がないので、割り当てミスの原因の一つが解消されます
new 演算子は、こうして割り当てたメモリへのポインタを返します
問題は、容量の関係でメモリを割り当てられなかったときの処理です
標準 C++ では 例外 というものを生成します(例外については後述)
しかし、これは最近の話でこれまではずっと NULL を返していたのです
そのため、new がなにを返すかというのは、コンパイラによって違います
この講座は 標準C++ に基いて解説しているので、NULLを返すことは想定しません
//将来的には 標準C++ で統一されることが考えられます
new で割り当てたメモリ領域は、解放する必要があります
malloc() 関数に対し free() 関数でメモリの割り当てを解放していたのと同じです
new で割り当てたメモリは delete 演算子 で解放します
delete pointer;
pointer には、new で割り当てたメモリ領域へのポインタ変数を指定します
それ以外のポインタを渡すと、プログラムがクラッシュする可能性があります
#include <iostream>
using namespace std;
int main() {
int *po;
po = new int;
*po = 100;
cout << "動的に割り当てたメモリの内容 = " << *po;
delete po;
return 0;
}
失敗した時の処理はしていません
ここで割り当てるメモリサイズはごくわずかなものなので、まず失敗はしないでしょう
オブジェクトの割り当て
クラス型のオブジェクトを動的に割り当てることも可能です
このとき、データ型と違うのは初期値を与えると言う処理があることです
new Object(initializer);
Object には、オブジェクトを指定し
initializer には、オブジェクトの初期値を指定します
#include <iostream>
using namespace std;
class Kitty {
public:
Kitty(char *str) {
cout << str;
}
};
int main() {
Kitty *obj;
obj = new Kitty("Kitty on your lap\n");
delete obj;
return 0;
}
delete でメモリを解放した時に、デストラクタ関数が呼び出されます
配列の割り当て
new 演算子で1次元配列を動的に割り当てることもできます
ただし、配列の場合は初期化できないので注意してください
new type[size];
type には型を、size には割り当てる配列のサイズを指定します
配列を要求した場合 new 演算子は割り当てた配列の先頭へのポインタを返します
この場合、delete も次の構文を使わなくてはいけません
delete [] pointer;
pointer には、new で割り当てた配列の先頭へのポインタを指定します
[] の中には何も指定しませんが、古いCでは割り当てたサイズの指定が必要でした
現在のコンパイラでは、[]の中にサイズを指定しても無視します
#include <iostream>
using namespace std;
class Kitty {
public:
~Kitty() { cout << "Kitty on your lap\n"; }
};
int main() {
Kitty *obj;
obj = new Kitty[10];
delete [] obj;
return 0;
}
クラス型の配列を動的に割り当てた場合
メモリ解放時には、全ての要素が解放されるため
配列内の全てのオブジェクトのデストラクタが実行されます
ただし、new で割り当てた領域が複数回解放されているわけではありません
new
指定したデータ型またはオブジェクトの領域を
メモリのヒープ領域に割り当て、そのポインタを返します
delete
割り当てたメモリ領域を開放します
必ず new で割り当てた領域を指定してください