スポンサーリンク

| キーワード:

C++ std::vector resizeとreserveの違い

resize()とreserve()の違い。

一言で言うと、end()の位置が違う。 あと、resizeするとその個数分のコンストラクタが走る。

それぞれのend()の位置

 

resize_reserve_0

end()の位置が違うので、push_backした時の挙動が異なる

resizeしてからのpush_back

resize_reserve_2

 

 

 

reserveしてからのpush_back

resize_reserve_3

 

解説:

vectorはnewのラッパーであるから、newの使い方から考えると分かりやすい。

resizeにせよreserveにせよ、その分のメモリを確保することに変わりはない。

これがうれしいときはreserve:

・push_backした時に「使用済みの要素の次の要素」に値が入る。リストの末尾に追加していくような感じになる。size()を見れば保存した項目の個数がわかる。

・少なくともreserveで指定した回数分のpush_backに関しては、再確保が発生しないことが保障される。

これがうれしいときはresize:

・size()が確保した要素数になるので、普通の配列と同じように使える。

余談

動作の違いから、resizeした後にpush_backすることは少ない。

また逆に、reserveしてから、size()以上の要素に対してoperator[]でアクセスしてはいけない。

これらのことをやっているコードは、バグである可能性がある(特に後者)

 

余談だが、こんなことをしてもいいかもしれない。

 

	std::vector<char> v;
	v.reserve(100*100); //画像サイズは100*100が相場

	printf("100*100 size:%d capacity %d\n",v.size(),v.capacity() );
	v.resize(30*30); //実際には30*30に設定された
	printf("30*30 size:%d capacity %d\n",v.size(),v.capacity() );
	v.resize(50*50); //わけあって50*50に変更した
	printf("50*50 size:%d capacity %d\n",v.size(),v.capacity() );
	v.resize(200*200);//結局200*200も使ってしまった
	printf("200*200 size:%d capacity %d\n",v.size(),v.capacity() );

 

100*100 size: 0 capacity 10000
30*30 size: 900 capacity 10000
50*50 size: 2500 capacity 10000
200*200 size: 40000 capacity 40000

 

最初にある程度の大きさをreserveしてcapacityを広げておけば、後のresize時に再確保の可能性が減り、高速化が図れる(かも)。

 

あと、最初に書いたが、resizeした時はその分のコンストラクタが走る。

 

#include <vector>
class CC{
public:
	CC(){
		printf("construct...\n");
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	std::vector<CC> v;
	v.reserve(100);
	v.resize(5);
	getchar();

	return 0;
}

 

実行結果:resizeした5個分のコンストラクタが走っている

construct…
construct…
construct…
construct…
construct…

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: