resize()とreserve()の違い。
一言で言うと、end()の位置が違う。 あと、resizeするとその個数分のコンストラクタが走る。
end()の位置が違うので、push_backした時の挙動が異なる
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...