Namespaces
Variants

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

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

Incrementa la capacidad del vector (el número total de elementos que el vector puede contener sin requerir reasignación) a un valor mayor o igual a new_cap . Si new_cap es mayor que la capacity() actual, se asigna nuevo almacenamiento; de lo contrario, la función no hace nada.

reserve() no cambia el tamaño del vector.

Si new_cap es mayor que capacity() , todos los iteradores (incluyendo el iterador end() ) y todas las referencias a los elementos quedan invalidados. De lo contrario, ningún iterador o referencia queda invalidado.

Después de una llamada a reserve() , las inserciones no activarán la reasignación a menos que la inserción haría que el tamaño del vector sea mayor que el valor de capacity() .

Contenidos

Parámetros

new_cap - nueva capacidad del vector, en número de elementos
Requisitos de tipo
-
T debe cumplir con los requisitos de MoveInsertable en * this . (desde C++11)

Valor de retorno

(ninguno)

Excepciones

Si se lanza una excepción, esta función no tiene efecto ( strong exception guarantee ).

Si el constructor de movimiento de T no es noexcept y T no es CopyInsertable en * this , vector utilizará el constructor de movimiento que lanza excepciones. Si lanza una excepción, la garantía se suspende y los efectos no están especificados.

(desde C++11)

Complejidad

Como máximo lineal en el size() del contenedor.

Notas

El uso correcto de reserve() puede prevenir reasignaciones innecesarias, pero usos inapropiados de reserve() (por ejemplo, llamarlo antes de cada push_back() ) pueden realmente incrementar el número de reasignaciones (al hacer que la capacidad crezca linealmente en lugar de exponencialmente) y resultar en mayor complejidad computacional y menor rendimiento. Por ejemplo, una función que recibe un vector arbitrario por referencia y le añade elementos normalmente no debería llamar reserve() en el vector, ya que no conoce las características de uso del vector.

Al insertar un rango, la versión de rango de insert() generalmente es preferible ya que preserva el comportamiento correcto de crecimiento de capacidad, a diferencia de reserve() seguido por una serie de push_back() s.

reserve() no puede utilizarse para reducir la capacidad del contenedor; para ese propósito shrink_to_fit() está disponible.

Ejemplo

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

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Se aplica a Comportamiento publicado Comportamiento correcto
LWG 329 C++98 podría desencadenarse una reasignación si una inserción
hace que el tamaño del vector sea mayor que el tamaño
especificado en la llamada más reciente a reserve()
solo se desencadena si el tamaño
del vector se vuelve
mayor que capacity()
LWG 2033 C++11 T no se requería que fuera MoveInsertable requerido

Véase también

devuelve el número de elementos que pueden almacenarse en la memoria actualmente asignada
(función miembro pública)
devuelve el número máximo posible de elementos
(función miembro pública)
cambia el número de elementos almacenados
(función miembro pública)
reduce el uso de memoria liberando memoria no utilizada
(función miembro pública)