28


7

std :: vectorが下方向にサイズ変更

C標準は、 resize(n)n <size()、または `clear()`のいずれによっても、容量に対する副作用については何も述べていないようです。

それは push_back`と pop_back`の償却コストについての声明をします - O(1)

私は、CLRSアルゴリズム(例えば、 拡大するときは2倍、 `sizeを<capacity()/ 4にするときは半分にする (Cormen Lieserson Rivest Stein)

誰かが何らかの実装上の制限についての言及を持っていますか?

4 Answer


41


より小さなサイズで `resize()`を呼び出しても `vector`の容量には影響しません。 メモリを解放しません。

vector`からメモリを解放するための標準的な慣用句は、空の一時的な vector`を使って `swap()`することです: `std

vector()。swap(vec);`。 下方向にサイズ変更したい場合は、元のベクトルから新しいローカルの一時的なベクトルにコピーしてから、結果のベクトルを元のベクトルと交換する必要があります。

更新: C 11はこの目的のためにメンバー関数http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit [shrink_to_fit()]を追加しました、それは 容量を減らすための非束縛要求です() `から size() `へ。


24


実際には、規格は何が起こるべきかを指定しています:

これは vector`によるものですが、テーマはすべてのコンテナで同じです( list`、 `deque`など)。

_ 23.2.4.2ベクトル容量[lib.vector.capacity] _

void resize(size_type sz、T c = T());

_ {空} 6)効果: _

if (sz > size())
    insert(end(), sz-size(), c);
else if (sz < size())
    erase(begin()+sz, end());
else
    ; //do nothing

つまり、「resize」に指定されたサイズが要素数より少ない場合、それらの要素はコンテナから消去されます。 `capacity()`に関しては、これは `erase()`が何をするのかに依存します。

標準では見つかりませんが、clear()が次のように定義されていると確信しています。

void clear()
{
    erase(begin(), end());
}

それゆえ、 `clear()`が `capacity()`に及ぼす効果は、 `erase()`がそれに与える効果にも結び付けられます。 規格によると:

_ 23.2.4.3ベクトル修飾子[lib.vector.modifiers] _

iterator erase(iterator position);
iterator erase(iterator first, iterator last);

_ {空} 4)複雑さ:Tのデストラクタは、消去された要素の数に等しい回数と呼ばれます。 _

つまり、要素は破壊されますが、メモリはそのまま残ります。 erase()は容量には影響しません。したがって、resize()およびclear()も影響しません。


6


容量は決して減りません。 標準がこれを明示的に述べているかどうかはわかりませんが、暗示されています。反復子とvectorの要素への参照は、 `resize(n)`で無効にしてはいけません。


0


私はgcc(mingw)をチェックしたので、ベクトル容量を解放する唯一の方法はmattnewportが言うことです。 他の一時的なベクトルと交換します。 このコードはgcc用です。

template void shrinkContainer(C