C ++でのstd :: resize(n)とstd :: shrink_to_fitの違いは?


11

私はこれらの声明に出くわしました:

resize(n)–「n」要素が含まれるようにコンテナのサイズを変更します。
shrink_to_fit()–サイズに合わせてコンテナの容量を減らし、容量を超えるすべての要素を破棄します。

これらの機能に大きな違いはありますか?彼らはc ++のベクトルの下に来る


resizeはコンテナーのサイズを変更しますが、shrink_to_fitは変更しません。通常の使用では、shrink_to_fitについて知る必要はありません。これは、開発者が手動でコードのパフォーマンスを向上できるようにするためにのみ使用できます。
NoSenseEtAl

2
標準のコンテナにはサイズ容量があります。サイズはコンテナ内の現在の要素数であり、容量は割り当てられたメモリの量です(概算)。サイズを変更するとサイズがshrink_to_fit変わり、容量が変わります。
プログラマー

2
capacityとの違いを理解していますsizeか?
キュービック

回答:


12

ベクトルには、異なる意味を持つ2つの「長さ」属性があります。

  • sizeベクトルで使用可能な要素の数です。保管しているものの数です。これは概念的な長さです。
  • capacity ベクトルが現在割り当てているメモリの量に適合する要素の数です。

capacity >= size常に真でなければならないが、それらが常に等しい理由はない。たとえば、要素を削除する場合、割り当てを縮小するには、新しい割り当てを1バケット小さく作成し、残りのコンテンツを上に移動する必要があります( "割り当て、移動、解放")。

同様に、capacity == size要素を追加した場合、ベクターは1つの要素(別の「割り当て、移動、解放」操作)で割り当てを増やすことができますが、通常は複数の要素を追加します。容量を増やす必要がある場合、ベクターはその容量を複数の要素で増やします。これにより、すべてを再度移動する必要がある前に、さらにいくつかの要素を追加できます。

この知識があれば、私たちはあなたの質問に答えることができます:

  • std::vector<T>::resize()配列のサイズを変更します。現在のサイズよりも小さいサイズに変更すると、余分なオブジェクトは破棄されます。現在のサイズよりも大きいサイズに変更すると、最後に追加された「新しい」オブジェクトはデフォルトで初期化されます。
  • std::vector<T>::shrink_to_fit()現在のサイズに合わせて容量を変更するように求めます。(実装はこのリクエストを尊重する場合としない場合があります。それらは、容量を減らすかもしれませんが、サイズに等しくしない場合があります。それらは何もしない場合があります。)リクエストが満たされると、これにより、未使用部分の一部またはすべてが破棄されますベクトルの割り当て。通常、これはベクターの構築が完了したときに使用し、ベクターにアイテムを追加することはありません。(追加するアイテムの数が事前にわかっている場合は、何かstd::vector<T>::reserve()shrink_to_fit行うのではなく、アイテムを追加する前にベクトルを使用して通知する方がよいでしょう。)

そのためresize()概念的にベクトルに含まれるものの量を変更するために使用します

概念的にベクター内にあるものの量変更せずにshrink_to_fit()、ベクターが内部的に割り当てた余分なスペースを最小限に抑えるために使用します。


2
それshrink_to_fitはオール・オア・ナッシングではないことに注意してください。実装によっては、容量が途中で減少する場合があります。たとえば、ベクトル容量を2の累乗に制限する実装を考えてみます。
フランソワアンドリュー

5

shrink_to_fit() –サイズに合わせてコンテナの容量を減らし、容量を超えるすべての要素を破棄します。

それは何が起こるかについての誤った特徴付けです。機密的には、容量部分を超えるすべての要素を破壊することは正確ではありません。

C ++では、オブジェクトに動的メモリが使用される場合、2つのステップがあります。

  1. メモリはオブジェクトに割り当てられます。
  2. オブジェクトはメモリ位置で初期化/構築されます。

動的に割り当てられたメモリ内のオブジェクトが削除されると、2つのステップがあり、構築のステップをミラーリングしますが、逆の順序になります。

  1. 破壊されたメモリ位置のオブジェクト(組み込みタイプの場合、これは何もしません)。
  2. オブジェクトによって使用されるメモリが割り当て解除されます。

コンテナのサイズを超えて割り当てられるメモリは、単なるバッファです。それらは適切に初期化されたオブジェクトを保持しません。それは単なる生のメモリです。shrink_to_fit()追加のメモリがないことを確認しますが、それらの場所にオブジェクトはありませんでした。したがって、何も破壊されず、メモリのみが割り当て解除されます。


2

C ++標準によると、 shrink_to_fit

効果:shrink_to_fitは、capacity()をsize()に削減するための非バインドリクエストです。

と比較して resize

効果:sz <size()の場合、最後のsize()-sz要素をシーケンスから削除します。それ以外の場合は、sz-size()のデフォルトで挿入された要素をシーケンスに追加します。

関数が異なることをするのは明らかです。さらに、最初の関数にはパラメーターがありませんが、2番目の関数には2つのパラメーターさえあります。この関数shrink_to_fitは、メモリを再割り当てできますが、コンテナのサイズを変更しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.