1. 導入: なぜunique_ptrの配列アクセスが重要なのか
C++で動的にメモリを確保する場合、かつてはnew[]やdelete[]を使っていましたが、これらはメモリリークを引き起こしやすいという課題がありました。モダンC++では、メモリ管理を自動化するスマートポインタ「unique_ptr」を使うのが定石です。特に、配列を扱う際に「ポインタの機能」と「スマートポインタの安全性」を両立させることは、堅牢なプログラムを書くための第一歩となります。
2. 基礎知識: unique_ptrと配列の仕組み
unique_ptrは、特定のメモリ領域を「唯一の所有者」として管理するオブジェクトです。通常、unique_ptrは単一のオブジェクトを指しますが、テンプレート引数に型を指定する際、std::unique_ptr
3. 実装/解決策: 添字演算子の使い方
配列版unique_ptrを定義すれば、あとは通常の配列変数のように扱うことができます。内部的には、指定したインデックスのメモリ位置を正しく計算してアクセスしてくれます。デストラクタが自動的にdelete[]を呼び出してくれるため、手動でメモリ解放を気にする必要はありません。
4. サンプルプログラム
以下のコードは、配列版unique_ptrを作成し、添字アクセスで値を操作する基本的な例です。
include <iostream>
include <memory> // unique_ptrを使用するために必要
int main() {
// 5つの整数を格納できる配列を動的確保
// std::unique_ptr<int[]> とすることで配列として扱える
std::unique_ptr<int[]> arr(new int[5]);
// 添字アクセスで値を代入
arr[0] = 10;
arr[1] = 20;
arr[2] = 30; // 3番目の要素にアクセス
// 値の確認
for (int i = 0; i < 3; ++i) {
std::cout < "arr[" < i < "] = " < arr[i] < std::endl;
}
// スコープを抜けると自動的にメモリが解放されるため、deleteは不要です
return 0;
}
5. 応用・注意点: 現場で役立つアドバイス
注意点1: 単一版との混同
std::unique_ptr<int> と std::unique_ptr<int[]> は別物です。単一版に対して添字演算子を使おうとするとコンパイルエラーになります。配列を扱うときは必ずテンプレート引数に[]を忘れずに入れましょう。
注意点2: 境界チェックは行われない
std::vectorとは異なり、unique_ptrの添字アクセスには境界チェック(範囲外アクセスを検知する機能)が含まれていません。範囲外にアクセスすると未定義動作となり、プログラムがクラッシュする原因になります。配列のサイズは常に意識してコーディングしてください。
より安全な代替案
もし要素のサイズが動的に変わる可能性がある場合は、std::vectorを使用するのが最も安全で推奨される選択肢です。unique_ptrの配列版は「サイズが固定されているが、動的に確保する必要がある場合」の最適解として使い分けるのが現場の鉄則です。

コメント