Unterschied zwischen std :: resize (n) und std :: shrink_to_fit in C ++?


11

Ich bin auf folgende Aussagen gestoßen:

resize(n)- Ändert die Größe des Containers so, dass er 'n' Elemente enthält.
shrink_to_fit()- Reduziert die Kapazität des Containers auf seine Größe und zerstört alle Elemente, die über die Kapazität hinausgehen.

Gibt es einen signifikanten Unterschied zwischen diesen Funktionen? Sie kommen in c ++ unter Vektoren


resize ändert die Größe des Containers, shrink_to_fit nicht. Für den normalen Gebrauch müssen Sie sich nicht mit shrink_to_fit auskennen. Es ist nur verfügbar, damit Entwickler die Leistung ihres Codes manuell steigern können.
NoSenseEtAl

2
Standardbehälter haben eine Größe und eine Kapazität . Die Größe ist die aktuelle Anzahl der Elemente im Container, während die Kapazität die (ungefähr) zugewiesene Speichermenge ist. Durch Ändern der Größe wird die Größe und shrink_to_fitdie Kapazität geändert.
Ein Programmierer

2
Verstehst du den Unterschied zwischen capacityund size?
Cubic

Antworten:


12

Vektoren haben zwei "Längen" -Attribute, die unterschiedliche Bedeutungen haben:

  • sizeist die Anzahl der verwendbaren Elemente im Vektor. Dies ist die Anzahl der Dinge, die Sie gespeichert haben. Dies ist eine konzeptionelle Länge.
  • capacity ist, wie viele Elemente in die Speichermenge passen würden, die der Vektor aktuell zugewiesen hat.

capacity >= sizemuss immer wahr sein, aber es gibt keinen Grund dafür, dass sie immer gleich sind. Wenn Sie beispielsweise ein Element entfernen, müssen Sie zum Verkleinern der Zuordnung eine neue Zuordnung erstellen, die einen Bucket kleiner ist, und den verbleibenden Inhalt verschieben ("Zuweisen, Verschieben, Frei").

Wenn capacity == sizeSie ein Element hinzufügen, kann der Vektor die Zuordnung um ein Element erhöhen (eine weitere Operation "Zuweisen, Verschieben, Frei"), aber normalerweise fügen Sie mehr als ein Element hinzu. Wenn die Kapazität erhöht werden muss, erhöht der Vektor seine Kapazität um mehr als ein Element, sodass Sie mehrere weitere Elemente hinzufügen können, bevor Sie alles erneut verschieben müssen.

Mit diesem Wissen können wir Ihre Frage beantworten:

  • std::vector<T>::resize()Ändert die Größe des Arrays. Wenn Sie die Größe kleiner als die aktuelle Größe ändern, werden die überschüssigen Objekte zerstört. Wenn Sie die Größe größer als die aktuelle Größe ändern, werden die am Ende hinzugefügten "neuen" Objekte standardmäßig initialisiert.
  • std::vector<T>::shrink_to_fit()fordert Sie auf, die Kapazität an die aktuelle Größe anzupassen. (Implementierungen können diese Anforderung erfüllen oder nicht . Sie verringern möglicherweise die Kapazität, machen sie jedoch nicht gleich der Größe. Sie tun möglicherweise überhaupt nichts.) Wenn die Anforderung erfüllt ist, werden einige oder alle nicht verwendeten Teile von verworfen die Zuordnung des Vektors. Normalerweise verwenden Sie diese Option, wenn Sie mit dem Erstellen eines Vektors fertig sind und niemals ein weiteres Element hinzufügen. (Wenn Sie im Voraus wissen, wie viele Elemente Sie hinzufügen werden, ist es besser std::vector<T>::reserve(), den Vektor vor dem Hinzufügen von Elementen mitzuteilen, anstatt sich auf shrink_to_fitirgendetwas zu verlassen.)

Sie können also resize()ändern, wie viel Material konzeptionell im Vektor enthalten ist.

Sie können shrink_to_fit()den überschüssigen Speicherplatz minimieren, den der Vektor intern zugewiesen hat, ohne zu ändern, wie viel Material sich konzeptionell im Vektor befindet.


2
Beachten Sie, dass dies shrink_to_fitnicht alles oder nichts ist. Eine Implementierung kann die Kapazität teilweise reduzieren. Stellen Sie sich zum Beispiel eine Implementierung vor, die die Vektorkapazität auf Zweierpotenzen beschränkt.
François Andrieux

5

shrink_to_fit() - Reduziert die Kapazität des Containers auf seine Größe und zerstört alle Elemente, die über die Kapazität hinausgehen.

Das ist eine Fehlcharakterisierung dessen, was passiert. Insbesondere ist die Zerstörung aller Elemente über den Kapazitätsteil hinaus nicht genau.

Wenn in C ++ dynamisch Speicher für Objekte verwendet wird, gibt es zwei Schritte:

  1. Speicher wird für Objekte zugewiesen.
  2. Objekte werden an den Speicherstellen initialisiert / konstruiert.

Wenn Objekte im dynamisch zugewiesenen Speicher gelöscht werden, gibt es auch zwei Schritte, die die Konstruktionsschritte in umgekehrter Reihenfolge widerspiegeln:

  1. Objekte an den Speicherorten sind zerstört (für integrierte Typen ist dies ein Noop).
  2. Der von den Objekten verwendete Speicher wird freigegeben.

Der über die Größe des Containers hinaus zugewiesene Speicher ist nur ein Puffer. Sie enthalten keine ordnungsgemäß initialisierten Objekte. Es ist nur rohe Erinnerung. shrink_to_fit()stellt sicher, dass der zusätzliche Speicher nicht vorhanden ist, sich jedoch keine Objekte an diesen Speicherorten befinden. Daher wird nichts zerstört, nur der Speicher wird freigegeben.


2

Nach dem C ++ Standard relativ zu shrink_to_fit

Auswirkungen: shrink_to_fit ist eine unverbindliche Anforderung zum Reduzieren von Kapazität () auf Größe ().

und relativ zu resize

Effekte: Wenn sz <size (), werden die letzten size () - sz-Elemente aus der Sequenz gelöscht. Andernfalls werden sz - size () standardmäßig eingefügte Elemente an die Sequenz angehängt.

Es ist offensichtlich, dass die Funktionen verschiedene Dinge tun. Darüber hinaus hat die erste Funktion keinen Parameter, während die zweite Funktion sogar zwei Parameter hat. Die Funktion shrink_to_fitändert die Größe des Containers nicht, kann jedoch Speicher neu zuweisen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.