2009-10-08 6 views
14

Wenn ich am Anfang meines Programms einen std :: vector zu einer bestimmten Größe und Kapazität unter Verwendung von resize() und reserve() zugewiesen habe, ist es möglich, dass pop_back() die reservierte Kapazität "durchbrechen" und Neuzuweisungen verursachen kann?Ändert std :: vector.pop_back() die Vektorkapazität?

Antwort

18

Nein, der einzige Weg, ein Vektor-Fähigkeit ist der Swap-Trick

template< typename T, class Allocator > 
void shrink_capacity(std::vector<T,Allocator>& v) 
{ 
    std::vector<T,Allocator>(v.begin(),v.end()).swap(v); 
} 

und selbst das ist nicht garantiert werden nach der Norm zu schrumpfen. (Obwohl es schwer vorstellbar ist, eine Implementierung, wo es nicht funktionieren würde.)

Soweit ich weiß, die nächste Version des C++ - Standard (was früher C++ 0x war, aber jetzt wurde C++ 1x) wird std::vector<>::shrink_to_fit() haben.

+1

Ich würde sehr von diesem Trick aus drei Gründen abraten: 1. Die Funktion tut nicht unbedingt das, was sie sagt. 2 Durchbricht das Prinzip der "geringsten Überraschung" 3. Es entsteht potenziell eine enorme Menge an Overhead - ganz zu schweigen von potenziellen Nebenwirkungen des Kopierens statt des Verschiebens. – einpoklum

+0

@einpoklum: Ja, das ist ohne Bewegung, und daher heute suboptimal. Aber diese Antwort ist fast ein Jahrzehnt alt, also ... – sbi

+0

@sbi: Davon würde ich dann auch abraten :-( – einpoklum

4

Nein pop_back() wird die Kapazität des Vektors nicht verkleinern. Verwenden Sie stattdessen std::vector<T>(v).swap(v).

+0

Duplikat von @ sbi's Antwort; und sehe dort meinen Kommentar zum "Swap-Trick". – einpoklum

1

NR. Das gleiche wie push_back, pop_back wird keinen Einfluss auf die capacity(). Sie betreffen nur die size().

EDIT:

Ich hätte sagen sollen push_back nicht die Kapazität ändern, wenn die v.size() < v.capacity().

2

pop_XXX wird niemals die Kapazität ändern. push_XXX kann die Kapazität ändern, wenn Sie versuchen, mehr Daten zu übertragen, als die Kapazität erlaubt.

1

Hier ist der Code von std :: vector :: pop_back()

void pop_back() 
{ // erase element at end 
    if (!empty()) 
    { // erase last element 
     _Dest_val(this->_Alval, this->_Mylast - 1); 
     --this->_Mylast; 
    } 
} 

Funktion nur der Destructor ruft und nimmt Zeiger auf das letzte Element. Code von VC (Freigabe). Dies hat keine Auswirkungen auf die Kapazität (oder Reallokation) des Vektors.

+1

Eine bestimmte Implementierung ist nicht genug Informationen, um zu bestimmen, was der Standard erfordert, und dies ist möglicherweise nicht die gleiche Implementierung, die die Person verwendet, die die Frage stellt. –

4

Unter C++ 11 kann man shrink_to_fit() aufrufen, um nach einem Vektor (sowie einem Deque oder einer Zeichenkette) zu fragen, um den reservierten Platz auf die Kapazität des Vektors zu reduzieren. Beachten Sie jedoch, dass dies implementationsabhängig ist: es ist nur eine Anfrage und es gibt keine Garantie. Sie können den folgenden Code versuchen:

#include <iostream> 
#include <vector> 
using namespace std; 

int main(){ 
    vector<int> myVector; 

    for (auto i=1;i!=1e3;++i) 
     myVector.push_back(i); 

    cout << "Capacity: " << myVector.capacity() << endl; 
    myVector.reserve(2000); 
    cout << "Capacity (after reserving 2000): " << myVector.capacity() << endl; 
    myVector.shrink_to_fit(); 
    cout << "Capacity (after shrink_to_fit): " << myVector.capacity(); 

} 
Verwandte Themen