Namespaces
Variants

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

From cppreference.net
void reserve ( size_type new_cap ) ;
(constexpr depuis C++20)

Augmente la capacité du vecteur (le nombre total d'éléments que le vecteur peut contenir sans nécessiter de réallocation) à une valeur supérieure ou égale à new_cap . Si new_cap est supérieur à la capacity() actuelle, un nouveau stockage est alloué, sinon la fonction ne fait rien.

reserve() ne modifie pas la taille du vecteur.

Si new_cap est supérieur à capacity() , tous les itérateurs (y compris l'itérateur end() ) et toutes les références aux éléments sont invalidés. Sinon, aucun itérateur ou référence n'est invalidé.

Après un appel à reserve() , les insertions ne déclencheront pas de réallocation sauf si l'insertion rendrait la taille du vecteur supérieure à la valeur de capacity() .

Table des matières

Paramètres

new_cap - nouvelle capacité du vecteur, en nombre d'éléments
Exigences de type
-
T doit satisfaire aux exigences de MoveInsertable dans * this . (depuis C++11)

Valeur de retour

(aucun)

Exceptions

Si une exception est levée, cette fonction n'a aucun effet ( strong exception guarantee ).

Si le constructeur de déplacement de T n'est pas noexcept et que T n'est pas CopyInsertable dans * this , le vecteur utilisera le constructeur de déplacement pouvant lever des exceptions. S'il lève une exception, la garantie est abandonnée et les effets ne sont pas spécifiés.

(depuis C++11)

Complexité

Au plus linéaire en la size() du conteneur.

Notes

Utiliser correctement reserve() peut éviter des réallocations inutiles, mais des utilisations inappropriées de reserve() (par exemple, l'appeler avant chaque push_back() ) peuvent en réalité augmenter le nombre de réallocations (en provoquant une croissance linéaire plutôt qu'exponentielle de la capacité) et entraîner une complexité computationnelle accrue ainsi qu'une diminution des performances. Par exemple, une fonction qui reçoit un vecteur arbitraire par référence et y ajoute des éléments ne devrait généralement pas appeler reserve() sur le vecteur, car elle ne connaît pas les caractéristiques d'utilisation du vecteur.

Lors de l'insertion d'une plage, la version de plage de insert() est généralement préférable car elle préserve le comportement correct de croissance de la capacité, contrairement à reserve() suivi d'une série d'appels push_back() .

reserve() ne peut pas être utilisé pour réduire la capacité du conteneur ; à cette fin, shrink_to_fit() est fourni.

Exemple

#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);
        }
    }
}

Sortie possible :

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

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR S'applique à Comportement publié Comportement corrigé
LWG 329 C++98 une réallocation pouvait être déclenchée si une insertion
rendait la taille du vecteur supérieure à la taille
spécifiée dans l'appel le plus récent à reserve()
déclenchée uniquement si la taille
du vecteur devient
supérieure à capacity()
LWG 2033 C++11 T n'était pas requis d'être MoveInsertable requis

Voir aussi

renvoie le nombre d'éléments pouvant être contenus dans le stockage actuellement alloué
(fonction membre publique)
renvoie le nombre maximum possible d'éléments
(fonction membre publique)
modifie le nombre d'éléments stockés
(fonction membre publique)
réduit l'utilisation de la mémoire en libérant la mémoire inutilisée
(fonction membre publique)