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
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.
Nein pop_back() wird die Kapazität des Vektors nicht verkleinern. Verwenden Sie stattdessen std::vector<T>(v).swap(v)
.
Duplikat von @ sbi's Antwort; und sehe dort meinen Kommentar zum "Swap-Trick". – einpoklum
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()
.
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.
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.
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. –
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();
}
- 1. Erhöhung der Vektorkapazität
- 2. Warum ändert sich std :: uncaught_exception in std :: uncaught_exceptions?
- 3. Ändert std :: sort die relative Reihenfolge gleicher Elemente?
- 4. C++ std :: vector :: size() ändert seinen Zustand
- 5. Warum ändert Operator() für Std :: Funktion in C++ 17?
- 6. Warum ändert der automatische Rückgabetyp die Überladungsauflösung?
- 7. DrawerLayout ändert die Empfindlichkeit?
- 8. MBProgressHUD ändert die Datenausgabe?
- 9. Kamerabild ändert die Ausrichtung
- 10. Wie die Verwendung von std :: bind mit std kombinieren :: shared_ptr
- 11. mehrere Threads, die auf std :: cout oder std :: cerr schreiben
- 12. Verknüpfte Liste, die den Knoten ändert, anstatt einen weiteren hinzuzufügen
- 13. Die Implementierung von std :: Vorwärts
- 14. Implementieren slice_shift_char die std Bibliothek
- 15. std :: copy std :: cout für std :: pair
- 16. std :: mit std :: make_pair
- 17. Wie kennt die std :: function die Aufrufkonvention?
- 18. std :: bind std :: function?
- 19. OpenCV - cvtColor ändert den Farbraum nicht, er ändert die Farben
- 20. Wie ändert sich die Codierung?
- 21. Wie ändert man die Pfeilspitze?
- 22. $ state.go ändert nicht die URL
- 23. RedirectToAction ändert nicht die URL
- 24. Warum ändert DOM die Codierung?
- 25. sollte std :: common_type std :: zerfallen?
- 26. std :: mem_fun vs std :: mem_fn
- 27. std :: konditional vs std :: enable_if
- 28. std :: any von std :: exception_ptr
- 29. std :: make_shared mit std :: initializer_list
- 30. Sortier std :: Listen std :: sort
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
@einpoklum: Ja, das ist ohne Bewegung, und daher heute suboptimal. Aber diese Antwort ist fast ein Jahrzehnt alt, also ... – sbi
@sbi: Davon würde ich dann auch abraten :-( – einpoklum