c++のvector
ではresize
とassign
という機能があります。
僕は今までresize
ではサイズの指定だけ、assign
はサイズと中身、とイメージしていたんですがresize
でも要素を指定できることを知ったので忘れないために違いを書いておこうと思います。
※簡単のためstd::
を省略しています。
resize
vector<int> a={1,2,3};
a.resize(5);
このようにするとaの中身は{1,2,3,0,0}
になります。resize
で増えた分は0になります。
vector<int> a={1,2,3};
a.resize(1);
このようにするとaの中身は{1}
になります。resize
で指定した長さになるまでerase
が行われるらしいです。
驚いたやつ
vector<int> a={1,2,3};
a.resize(5,10);
これが僕がこの記事を書こうと思った原因です。resize
って名前だから長さしか指定できないだろうと思ったらそんなことありませんでした。
このようにするとaの中身は{1,2,3,10,10}
になります。埋める際に指定した要素になります。縮んだ場合は要素を指定しても変わりません。
assign
vector<int> a={1,2,3};
a.assign(5,1);
このようにするとaの中身は{1,1,1,1,1}
になります。assign
では全ての要素を指定した要素で埋めます。
vector<int> a={1,2,3};
a.resize(5,1);
このようにするとaの中身は{1}
になります。伸びた場合と同様です。
vector<int> a;
a.assign({1,2,3,4,5});
vector<int> b;
b.assign(a.begin(),a.end());
リストでassign
やほかのvector
のイテレータなどもassign
は受け取ります。
あとがき
resize
やassign
でメモリが解放されるわけではないことに注意が必要です。
vector<int> a={1,2,3,4};
a.push_back(5);
とした場合、配列の中身は{1,2,3,4,5}
と5要素しかありませんがメモリ領域は6要素分確保されています。元が4,追加で2なので6です。新しく追加した場合はもともとのメモリ領域分の半分が新たに確保されます。
a.shrink_to_fit();
先ほどの状態からこのようにするとメモリ領域が5要素分になります。使っていないメモリを開放することができます。
また、
vector<int>().swap(a);
このようにswap
のメンバ関数で使っていないメモリの解放をすることができます。新しくvector
配列を作って中身を移動させています。
参考にさせていただいたサイトの方々です。より詳しく書かれています。2つ目の記事はvector
そのものを開放したい場合に参考にしてください。