std::vector<T,Allocator>:: reserve
|
void
reserve
(
size_type new_cap
)
;
|
(constexpr seit C++20) | |
Erhöhen Sie die Kapazität des Vektors (die Gesamtzahl der Elemente, die der Vektor ohne Neuzuweisung halten kann) auf einen Wert, der größer oder gleich new_cap ist. Wenn new_cap größer als die aktuelle capacity() ist, wird neuer Speicher zugewiesen, andernfalls tut die Funktion nichts.
reserve()
ändert nicht die Größe des Vektors.
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 Vectors größer als den Wert von
capacity()
machen.
Inhaltsverzeichnis |
Parameter
| new_cap | - | neue Kapazität des Vektors, in Anzahl der Elemente |
| Typanforderungen | ||
-
T
muss die Anforderungen von
MoveInsertable
in
*
this
erfüllen.
(seit C++11)
|
||
Rückgabewert
(keine)
Ausnahmen
- std::length_error falls new_cap > max_size ( ) .
-
Jede Ausnahme, die von
Allocator::allocate()geworfen wird (typischerweise std::bad_alloc ).
Wenn eine Exception ausgelöst wird, hat diese Funktion keine Auswirkung ( strong exception guarantee ).
|
Wenn
|
(seit C++11) |
Komplexität
Höchstens linear in der size() des Containers.
Hinweise
Die korrekte Verwendung von
reserve()
kann unnötige Neuzuweisungen verhindern, aber unangemessene Verwendungen von
reserve()
(zum Beispiel der Aufruf vor jedem
push_back()
-Aufruf) können tatsächlich die Anzahl der Neuzuweisungen erhöhen (indem sie bewirken, dass die Kapazität linear statt exponentiell wächst) und zu erhöhter Rechenkomplexität und verminderter Leistung führen. Beispielsweise sollte eine Funktion, die einen beliebigen Vektor per Referenz empfängt und Elemente daran anhängt, in der Regel
nicht
reserve()
auf dem Vektor aufrufen, da sie die Nutzungscharakteristiken des Vektors nicht kennt.
Beim Einfügen eines Bereichs ist die Bereichsversion von
insert()
generell 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; zu diesem Zweck wird
shrink_to_fit()
bereitgestellt.
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
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 |
Reallokation könnte ausgelöst werden, wenn eine Einfügung
die Größe des Vectors größer macht als die Größe, die im letzten Aufruf von
reserve()
angegeben wurde
|
wird nur ausgelöst, wenn die Größe
des Vectors größer wird als capacity() |
| LWG 2033 | C++11 |
T
war nicht erforderlich, um
MoveInsertable
zu sein
|
erforderlich |
Siehe auch
|
gibt die Anzahl der Elemente zurück, die im aktuell allozierten Speicher gehalten werden können
(öffentliche Elementfunktion) |
|
|
gibt die maximal mögliche Anzahl von Elementen zurück
(öffentliche Elementfunktion) |
|
|
ändert die Anzahl der gespeicherten Elemente
(öffentliche Elementfunktion) |
|
|
(
DR*
)
|
reduziert die Speichernutzung durch Freigabe ungenutzten Speichers
(öffentliche Elementfunktion) |