Seaside Laboratory

Posts

vector の reserve と resize と assign

ポインタ配列を作成して NULL で初期化、というありふれたコードを書いた。

int size = 100;
// ポインタ配列
std::vector< BAR* > lpbars;
// 予め確保
lpbars.reserve( size );
// NULL で初期化
std::fill_n( lpbars.begin(), size, static_cast< BAR* >(NULL) );

プログラムを実行すると fill_n のところでクラッシュしてしまう。原因がわからず暫く悩んでしまったが、reserve の挙動を勘違いしていただけだった。

void reserve(size_type new_cap);
領域を拡張することなしに少なくとも new_cap 個の要素を格納できるよう、領域を確保します。

reserve は capacity (領域) を増やすものであって、size (要素数) を増やすものではない。Effective STL でも触れられていたのにすっかり忘れていた。

再び勘違いしないよう、reserve と resize に assign を加えた早見表を作成した。説明を簡素にするため要素数が減少した際の挙動については触れていない。

関数 目的
void reserve(size_type new_cap) capacity を増やし領域を再確保する回数を減らす。
void resize(size_type count, T value = T()) 要素数を変更する。新たに追加された要素は指定値で初期化される。
void assign(size_type count, const T& value) 要素を指定値で置き換える。要素数が足りない場合は追加される。

先程のプログラムの場合は、要素の追加と初期化を同時に行うので assign を使うのが良さそう。