std::vector<T,Allocator>::reserve
| void reserve( size_type new_cap ); |
(constexpr seit C++20) | |
Erhöht die Kapazität des Vektors (die Gesamtzahl der Elemente, die der Vektor ohne Neuzuweisung aufnehmen kann) auf einen Wert, der größer oder gleich new_cap ist. Wenn new_cap größer ist als die aktuelle capacity(), wird neuer Speicher alloziert, andernfalls tut die Funktion nichts.
reserve() ändert die Größe des Vektors nicht.
Wenn new_cap größer ist als capacity(), werden alle Iteratoren (einschließlich des end() Iterators) und alle Referenzen auf die Elemente ungültig. Andernfalls werden keine Iteratoren oder Referenzen ungültig.
Nach einem Aufruf von reserve() lösen Einfügungen keine Neuzuweisung aus, es sei denn, die Einfügung würde die Größe des Vektors größer machen als den Wert von capacity().
Inhalt |
[edit] Parameter
| new_cap | - | neue Kapazität des Vektors, in Anzahl von Elementen |
| Typanforderungen | ||
-T muss die Anforderungen von MoveInsertable in *this erfüllen. (seit C++11) | ||
[edit] Rückgabewert
(keine)
[edit] Ausnahmen
- std::length_error, wenn new_cap > max_size().
- Alle Ausnahmen, die von
Allocator::allocate()ausgelöst werden (typischerweise std::bad_alloc).
Wenn eine Ausnahme ausgelöst wird, hat diese Funktion keine Auswirkung (starke Ausnahme-Garantie).
|
Wenn der Move-Konstruktor von |
(seit C++11) |
[edit] Komplexität
Höchstens linear zur size() des Containers.
[edit] Hinweise
Die korrekte Verwendung von reserve() kann unnötige Neuzuweisungen verhindern. Unangemessene Verwendungen von reserve() (z.B. Aufruf vor jedem push_back()) können die Anzahl der Neuzuweisungen tatsächlich erhöhen (indem die Kapazität linear statt exponentiell wächst) und zu erhöhter Berechnungskomplexität und reduzierter Leistung führen. Eine Funktion, die einen beliebigen Vektor per Referenz empfängt und Elemente anhängt, sollte normalerweise nicht reserve() auf dem Vektor aufrufen, da sie die Nutzungseigenschaften des Vektors nicht kennt.
Beim Einfügen eines Bereichs ist die Bereichsversion von insert() im Allgemeinen vorzuziehen, da sie das korrekte Kapazitätswachstumsverhalten beibehält, im Gegensatz zu reserve() gefolgt von einer Reihe von push_back()s.
reserve() kann nicht verwendet werden, um die Kapazität des Containers zu verringern. Dazu wird shrink_to_fit() bereitgestellt.
[edit] Beispiel
#include <cstddef> #include <iostream> #include <new> #include <vector> // minimal C++11 allocator with debug output template<class Tp> struct NAlloc { typedef Tp value_type; NAlloc() = default; template<class T> NAlloc(const NAlloc<T>&) {} Tp* allocate(std::size_t n) { n *= sizeof(Tp); Tp* p = static_cast<Tp*>(::operator new(n)); std::cout << "allocating " << n << " bytes @ " << p << '\n'; return p; } void deallocate(Tp* p, std::size_t n) { std::cout << "deallocating " << n * sizeof *p << " bytes @ " << p << "\n\n"; ::operator delete(p); } }; template<class T, class U> bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; } template<class T, class U> bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; } int main() { constexpr int max_elements = 32; std::cout << "using reserve: \n"; { std::vector<int, NAlloc<int>> v1; v1.reserve(max_elements); // reserves at least max_elements * sizeof(int) bytes for (int n = 0; n < max_elements; ++n) v1.push_back(n); } std::cout << "not using reserve: \n"; { std::vector<int, NAlloc<int>> v1; for (int n = 0; n < max_elements; ++n) { if (v1.size() == v1.capacity()) std::cout << "size() == capacity() == " << v1.size() << '\n'; v1.push_back(n); } } }
Mögliche Ausgabe
using reserve: allocating 128 bytes @ 0xa6f840 deallocating 128 bytes @ 0xa6f840 not using reserve: size() == capacity() == 0 allocating 4 bytes @ 0xa6f840 size() == capacity() == 1 allocating 8 bytes @ 0xa6f860 deallocating 4 bytes @ 0xa6f840 size() == capacity() == 2 allocating 16 bytes @ 0xa6f840 deallocating 8 bytes @ 0xa6f860 size() == capacity() == 4 allocating 32 bytes @ 0xa6f880 deallocating 16 bytes @ 0xa6f840 size() == capacity() == 8 allocating 64 bytes @ 0xa6f8b0 deallocating 32 bytes @ 0xa6f880 size() == capacity() == 16 allocating 128 bytes @ 0xa6f900 deallocating 64 bytes @ 0xa6f8b0 deallocating 128 bytes @ 0xa6f900
[edit] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 329 | C++98 | Neuzuweisung kann ausgelöst werden, wenn eine Einfügung die Größe des Vektors größer macht als die Größe, die im letzten Aufruf von reserve() angegeben wurde |
wird nur ausgelöst, wenn die Größe des Vektors größer als capacity() wird |
| LWG 2033 | C++11 | T musste nicht MoveInsertable sein |
Gefordert |
[edit] Siehe auch
| Gibt die Anzahl der Elemente zurück, die im derzeit zugewiesenen Speicher gehalten werden können (public member function) | |
| Gibt die maximal mögliche Anzahl von Elementen zurück (public member function) | |
| ändert die Anzahl der gespeicherten Elemente (public member function) | |
| (DR*) |
reduziert den Speicherverbrauch durch Freigabe von ungenutztem Speicher (public member function) |