Namespaces
Variants

std::vector<T,Allocator>:: reserve

From cppreference.net
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

Wenn eine Exception ausgelöst wird, hat diese Funktion keine Auswirkung ( strong exception guarantee ).

Wenn T 's Move-Konstruktor nicht noexcept ist und T nicht CopyInsertable in * this ist, wird vector den werfenden Move-Konstruktor verwenden. Wenn dieser wirft, ist die Garantie aufgehoben und die Effekte sind nicht spezifiziert.

(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)
reduziert die Speichernutzung durch Freigabe ungenutzten Speichers
(öffentliche Elementfunktion)