動的配列の基本
C++では、動的配列は一般的にヒープメモリ上に確保されます。動的配列は、そのサイズが実行時に決定される配列です。これは、配列のサイズがコンパイル時にはわからない場合や、大量のデータを格納する必要がある場合に非常に便利です。
動的配列を作成するには、new
演算子を使用します。以下に例を示します。
int* array = new int[10]; // 10要素の動的配列を作成
このコードは、10個の整数を格納できる動的配列を作成します。new
演算子は、指定した数の連続したメモリブロックを確保し、その最初のアドレスを返します。このアドレスは、ポインタ変数array
に格納されます。
動的配列を使用し終わったら、必ずdelete[]
演算子を使用してメモリを解放する必要があります。これを忘れると、メモリリークが発生します。
delete[] array; // メモリを解放
以上が、C++における動的配列の基本的な使い方です。次のセクションでは、関数の引数として動的配列をどのように使用するかについて説明します。
関数の引数としての動的配列
C++では、関数の引数として動的配列を使用することができます。これは、大量のデータを関数に渡す必要がある場合や、関数内でデータを操作した結果を呼び出し元に返す場合に便利です。
動的配列を関数の引数として使用するには、ポインタを引数に取る関数を定義します。以下に例を示します。
void printArray(int* array, int size) {
for (int i = 0; i < size; i++) {
cout << array[i] << " ";
}
cout << endl;
}
この関数は、整数の動的配列とそのサイズを引数に取り、配列のすべての要素を出力します。関数を呼び出す際には、動的配列のポインタと配列のサイズを引数に渡します。
int* array = new int[10];
// 配列を初期化
for (int i = 0; i < 10; i++) {
array[i] = i;
}
printArray(array, 10); // 配列を出力
delete[] array; // メモリを解放
以上が、C++における関数の引数としての動的配列の使用方法です。次のセクションでは、動的配列の操作と注意点について説明します。
動的配列の操作と注意点
C++の動的配列は非常に強力なツールですが、適切に使用しないと問題が発生する可能性があります。以下に、動的配列の操作と注意点について説明します。
配列のインデックス
動的配列の要素にアクセスするには、配列名とインデックスを使用します。インデックスは0から始まります。したがって、array[0]
は配列の最初の要素を、array[size-1]
は配列の最後の要素を参照します。
int* array = new int[10];
for (int i = 0; i < 10; i++) {
array[i] = i;
}
配列の範囲外アクセス
配列の範囲外にアクセスすると、未定義の動作が発生します。これは、メモリの保護されていない部分にアクセスしようとすると発生します。したがって、配列の範囲外にアクセスしないように注意する必要があります。
int* array = new int[10];
array[10] = 0; // 配列の範囲外にアクセスしている
メモリリーク
動的配列を使用し終わったら、必ずdelete[]
演算子を使用してメモリを解放する必要があります。これを忘れると、メモリリークが発生します。メモリリークは、プログラムが使用していないメモリを解放しない結果、次第にシステムのメモリが枯渇してしまう現象です。
int* array = new int[10];
// 配列を使用
delete[] array; // メモリを解放
以上が、C++における動的配列の操作と注意点です。次のセクションでは、動的配列とstd::vectorについて説明します。
動的配列とstd::vector
C++の動的配列は非常に強力ですが、その使用には注意が必要です。一方、C++の標準ライブラリには、動的配列の多くの問題を解決するstd::vector
というクラスがあります。
std::vectorの基本
std::vector
は、動的配列と同じように動作しますが、サイズの変更、要素の追加、メモリの管理などが自動的に行われます。これにより、動的配列の使用に関連する多くの問題を回避できます。
#include <vector>
std::vector<int> vec(10); // 10要素のstd::vectorを作成
for (int i = 0; i < 10; i++) {
vec[i] = i;
}
std::vectorの利点
std::vector
の最大の利点は、その柔軟性と安全性です。std::vector
は自動的にリサイズされ、必要に応じてメモリを確保および解放します。これにより、メモリリークのリスクが大幅に減少します。
また、std::vector
は範囲チェックを提供するat()
メソッドを提供しています。これにより、配列の範囲外アクセスを防ぐことができます。
try {
vec.at(10) = 0; // 範囲外アクセスを試みる
} catch (std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << std::endl;
}
以上が、C++における動的配列とstd::vector
の比較です。std::vector
は、その安全性と便利さから、動的配列よりも推奨されることが多いです。しかし、動的配列が必要な場合もありますので、それぞれの特性を理解し、適切に使用することが重要です。次のセクションでは、さらに詳しく説明します。