C++で動的2次元配列

素数が、小さなコンパイル時定数なら int a[Y][X]; でいいのだが、動的に確保しようとすると2次元配列はけっこう面倒。大抵は一番上の方法で足りるけど、下のほうの方法も別に遅くはない。どれも a[2][1] = 3; などと普通に使える。
ここでは、説明のために a[Y][X] という配列を Y行X列の2次元配列 と呼ぶ。

行の長さが定数の場合

列数Xがコンパイル時定数の場合。一般の多次元配列なら、最初の要素数(下のソースだとy)以外が全て定数のときに使える。簡単・高速なので、メモリが足りないとき以外はこれがいい。

#include <vector>

const int X = 4; // コンパイル時定数
int y = 3;
std::vector<int[X]> a(y);

素数が定数でない場合

メモリを節約したいときは自前のクラスを作る。多次元配列で必要な乗算が、コンパイル時定数との乗算でないため、わずかに遅くなるはず。

#include <vector>

template <class T> class Array2d {
    const size_t x_;
    std::vector<T> v_;
public:
    Array2d(size_t x, size_t y) : x_(x), v_(std::vector<T>(x * y)) {}
    T *operator[](size_t y) { return &v_[x_ * y]; }
};

int x = 4, y = 3;
Array2d<int> a(x, y);

配列の配列

各行の要素数を別々に設定できる。下の例だと、まず各行の要素数を4で初期化してから、a[1]の行だけ2に減らしている。各行の先頭アドレスがばらばらなので、扱いにくい面がある。

#include <vector>

int x = 4, y = 3;
std::vector<std::vector<int>> a(y, std::vector<int>(x));

a[1] = std::vector<int>(2);