2009-07-20 31 views
23

C++標準では、容量の副作用に関する記述は、 resize(n)n < size()、またはclear()のいずれも記載されていないようです。std :: vector resize down

それはpush_backpop_backの償却原価に関する声明作るん - (私は容量の通常のソートがCLRSアルゴリズムALA を変更しない実装を想像することができますO(1)

を例えば拡大したときに、二重、半減減少する。size to < capacity()/4)。 (Cormen Lieserson Rivest Stein)

実装に関する制限事項はありますか?

答えて

34

小さいサイズのresize()を呼び出すことは、vectorの容量には影響しません。それはメモリを解放しません。

vectorからメモリを解放するための標準的なイディオムは、空の一時vectorでそれswap()にある:std::vector<T>().swap(vec);。下にサイズを変更する場合は、元のベクターから新しいローカルの一時ベクターにコピーしてから、結果のベクターを元のベクターにスワップする必要があります。

更新日: C++ 11は、それがsize()capacity()を減らすために非結合要求だ、この目的のためにメンバ関数shrink_to_fit()を追加しました。

+0

私はそれを読んで、彼はメモリ使用量への影響を尋ねています。彼は具体的に容量の影響がどのようなものかを尋ねています。その基準はその場合の結果を指定するものではありませんが、私が考えることができる唯一の理由は、未使用のメモリを解放するという希望です。一時的なやりとりを伴うスワップは、それを達成するための慣習的な方法です。 – mattnewport

+2

標準では、これらの操作のcapacity()の減少を指定しないことで結果を指定しています。したがって、それを減らすことはできません。 – MSalters

+2

初期の「構築」段階の後にメモリの割り当てや解放を禁止する環境があります。この環境では、操作中にメモリの割り当てや解放を行わないことが保証されている限り、ベクターを使用できます。だから、この質問はこの状況に関連している(私をここに連れて来た)。 – meowsqueak

21

実際には、標準ではどうするかを指定しない:

これはvectorからですが、テーマはすべてのコンテナで同じです(listdeque、等...)

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。これは、要素を意味Tのデストラクタが消去された要素の数に等しい回数と呼ばれる....

:修飾子]

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

4)複雑破壊されますが、メモリは元のままです。 erase()は容量に影響を与えません。したがって、resize()clear()も効果がありません。

+0

Perrhaps少し標準的すぎますか?私はあなたの結論に同意しますが、その多くは本当に問題に対処していません。 –

+0

合意。私は少し下に切り取った。 :) – GManNickG

+0

あなたはそれをあまりにも多く切り取った、 "効果"段落は '予約'ではなく 'サイズ変更'のためのものです。 ;) – avakar

4

容量は決して減少しません。標準でこれを明示的に述べているかどうかはわかりませんが、それは暗示されています。ベクトルの要素に対するイテレータと参照は、によって無効化されてはなりません。n < capacity()

0

私はgcc(mingw)をチェックしたので、ベクトル容量を解放する唯一の方法はmattnewportが言うことです。 他のteporaryベクターでスワップします。 このコードはgccになります。

template<typename C> void shrinkContainer(C &container) { 
    if (container.size() != container.capacity()) { 
     C tmp = container; 
     swap(container, tmp); 
    } 
    //container.size() == container.capacity() 
} 
関連する問題