[C++] new deleteの使い方についてわかりやすく解説
C++では、動的メモリ管理を行うためにnew
とdelete
を使用します。
new
は、指定した型のメモリをヒープ領域に確保し、そのメモリのアドレスを返します。
例えば、int* ptr = new int;
は整数型のメモリを確保し、そのアドレスをptr
に格納します。
一方、delete
はnew
で確保したメモリを解放します。
メモリリークを防ぐため、delete ptr;
のように使用し、確保したメモリを適切に解放することが重要です。
配列の場合はdelete[]
を使用します。
new
とdelete
の基本的な使い方- メモリリークの概念とその防止方法
- 配列の動的メモリ確保の方法
- カスタムデリータの実装方法
- スマートポインタの利点と使用方法
newとdeleteの基本
new演算子とは
new
演算子は、C++において動的にメモリを確保するための演算子です。
これにより、プログラムの実行中に必要なメモリを確保し、オブジェクトを生成することができます。
new
を使用することで、スタックではなくヒープ領域にメモリを割り当てることができ、プログラムの実行が終了するまでそのメモリを保持することが可能です。
以下は、new
演算子を使用してオブジェクトを生成する例です。
class Sample {
public:
Sample() {
// コンストラクタ
}
void display() {
std::cout << "Sampleクラスのオブジェクトです。" << std::endl;
}
};
int main() {
Sample* obj = new Sample(); // new演算子でメモリを確保
obj->display();
// メモリの解放は後で行う
}
Sampleクラスのオブジェクトです。
delete演算子とは
delete
演算子は、new
演算子で確保したメモリを解放するために使用されます。
メモリを解放することで、メモリリークを防ぎ、プログラムの効率を向上させることができます。
delete
を使用する際は、必ず対応するnew
で確保したメモリを解放する必要があります。
以下は、delete
演算子を使用してメモリを解放する例です。
delete obj; // 確保したメモリを解放
newとdeleteの基本的な使い方
new
とdelete
の基本的な使い方は以下の通りです。
これらを正しく使用することで、動的メモリ管理を適切に行うことができます。
以下の表に、new
とdelete
の基本的な使い方をまとめました。
演算子 | 説明 | 使用例 |
---|---|---|
new | メモリを動的に確保する | Sample* obj = new Sample(); |
delete | 確保したメモリを解放する | delete obj; |
new[] | 配列のメモリを動的に確保する | int* arr = new int[10]; |
delete[] | 配列のメモリを解放する | delete[] arr; |
これらの基本を理解することで、C++におけるメモリ管理の基礎を築くことができます。
メモリ管理の重要性
メモリリークとは
メモリリークとは、プログラムが動的に確保したメモリを解放せずに失ってしまう現象を指します。
これにより、使用可能なメモリが徐々に減少し、最終的にはプログラムがクラッシュしたり、システム全体のパフォーマンスが低下したりする原因となります。
特に長時間実行されるプログラムや、メモリを多く使用するアプリケーションでは、メモリリークの影響が顕著に現れます。
以下は、メモリリークの例です。
void memoryLeakExample() {
int* leak = new int[100]; // メモリを確保
// leakをdeleteしないため、メモリが解放されない
}
メモリリークの防止方法
メモリリークを防ぐためには、以下の方法を実践することが重要です。
これらの方法を用いることで、メモリ管理を適切に行うことができます。
方法 | 説明 |
---|---|
deleteを忘れない | new で確保したメモリは必ずdelete で解放する。 |
スコープを意識する | 自動変数を使用し、スコープが終了すると自動的に解放されるようにする。 |
スマートポインタを使用 | std::unique_ptr やstd::shared_ptr を使用して、メモリ管理を自動化する。 |
スマートポインタとの比較
スマートポインタは、C++11以降に導入されたメモリ管理のためのクラスで、動的に確保したメモリを自動的に解放する機能を持っています。
これにより、メモリリークのリスクを大幅に減少させることができます。
以下に、一般的なスマートポインタの種類とその特徴を示します。
スマートポインタの種類 | 説明 | 使用例 |
---|---|---|
std::unique_ptr | 唯一の所有権を持つポインタ。自動的にメモリを解放。 | std::unique_ptr<Sample> ptr = std::make_unique<Sample>(); |
std::shared_ptr | 複数のポインタが同じメモリを共有。参照カウントで管理。 | std::shared_ptr<Sample> ptr = std::make_shared<Sample>(); |
std::weak_ptr | shared_ptr の所有権を持たないポインタ。循環参照を防ぐ。 | std::weak_ptr<Sample> weakPtr = ptr; |
スマートポインタを使用することで、手動でメモリを管理する必要がなくなり、プログラムの安全性と可読性が向上します。
これにより、メモリリークのリスクを大幅に軽減することができます。
newとdeleteの応用
配列の動的メモリ確保
C++では、new
演算子を使用して配列の動的メモリを確保することができます。
配列を動的に確保することで、実行時に必要なサイズの配列を作成することが可能になります。
以下は、配列の動的メモリ確保の例です。
int main() {
int size = 5;
int* arr = new int[size]; // 配列の動的メモリ確保
// 配列に値を代入
for (int i = 0; i < size; ++i) {
arr[i] = i * 10;
}
// 配列の値を表示
for (int i = 0; i < size; ++i) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
delete[] arr; // 配列のメモリを解放
}
0 10 20 30 40
カスタムデリータの使用
カスタムデリータは、std::unique_ptr
やstd::shared_ptr
と組み合わせて使用することで、特定の条件や処理に基づいてメモリを解放することができます。
これにより、リソースの管理をより柔軟に行うことが可能になります。
以下は、カスタムデリータの使用例です。
#include <iostream>
#include <memory>
void customDeleter(int* p) {
std::cout << "カスタムデリータが呼ばれました。" << std::endl;
delete p; // メモリを解放
}
int main() {
std::unique_ptr<int, decltype(&customDeleter)> ptr(new int(42), customDeleter);
std::cout << "値: " << *ptr << std::endl;
// ptrがスコープを抜けるとカスタムデリータが呼ばれる
}
値: 42
カスタムデリータが呼ばれました。
クラスとnew/deleteの関係
C++では、クラスのインスタンスを動的に生成する際にnew
演算子を使用し、インスタンスが不要になった際にはdelete
演算子を使用してメモリを解放します。
クラスのコンストラクタとデストラクタは、new
とdelete
の使用において重要な役割を果たします。
以下は、クラスとnew
/delete
の関係を示す例です。
class MyClass {
public:
MyClass() {
std::cout << "MyClassのコンストラクタが呼ばれました。" << std::endl;
}
~MyClass() {
std::cout << "MyClassのデストラクタが呼ばれました。" << std::endl;
}
};
int main() {
MyClass* obj = new MyClass(); // コンストラクタが呼ばれる
delete obj; // デストラクタが呼ばれる
}
MyClassのコンストラクタが呼ばれました。
MyClassのデストラクタが呼ばれました。
このように、クラスのインスタンスを動的に生成する際には、new
とdelete
を適切に使用することで、リソースの管理を行うことができます。
よくある質問
まとめ
C++におけるnew
とdelete
の使い方を理解することで、動的メモリ管理の基礎を築くことができます。
メモリリークを防ぐための方法やスマートポインタの利点を学ぶことで、より安全で効率的なプログラムを書くことが可能になります。
ぜひ、これらの知識を活用して、C++プログラミングのスキルを向上させてください。