Namensräume
Varianten
Aktionen

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

Von cppreference.com
< cpp‎ | container‎ | vector
 
 
 
 
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

Wenn eine Ausnahme ausgelöst wird, hat diese Funktion keine Auswirkung (starke Ausnahme-Garantie).

Wenn der Move-Konstruktor von T nicht noexcept ist und T nicht CopyInsertable in *this ist, verwendet der Vektor den werfenden Move-Konstruktor. Wenn dieser eine Ausnahme auslöst, entfällt die Garantie und die Auswirkungen sind undefiniert.

(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) [edit]
Gibt die maximal mögliche Anzahl von Elementen zurück
(public member function) [edit]
ändert die Anzahl der gespeicherten Elemente
(public member function) [edit]
reduziert den Speicherverbrauch durch Freigabe von ungenutztem Speicher
(public member function) [edit]