Skip to main content

std::vector reserve() method

// prism-push-types:size_type
// Non const version only
constexpr void reserve( size_type new_cap );

Increase the capacity of the vector (the total number of elements that the vector can hold without requiring reallocation) to a value that's greater or equal to new_cap. If new_cap is greater than the current capacity(), new storage is allocated, otherwise the function does nothing.

important

reserve() does not change the size of the vector.

Invalidation

If new_cap is greater than capacity(), all iterators, including the past-the-end iterator, and all references to the elements are invalidated.

Otherwise, no iterators or references are invalidated.

Parameters

  • new_cap - new capacity of the vector, in number of elements

Type requirements

  • T (the container's element type) must meet the requirements of MoveInsertable.

Return value

(none)

Complexity

At most linear in the size() of the container - O(sizes()).

Exceptions

If an exception is thrown, this function has no effect (strong exception guarantee).

If T's move constructor is not noexcept and T is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.

Notes

Correctly using reserve() can prevent unnecessary reallocations, but inappropriate uses of reserve() (for instance, calling it before every push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and result in increased computational complexity and decreased performance.

For example, a function that receives an arbitrary vector by reference and appends elements to it should usually not call reserve() on the vector, since it does not know of the vector's usage characteristics.

When inserting a range, the range version of insert() is generally preferable as it preserves the correct capacity growth behavior, unlike reserve() followed by a series of push_back()s.

reserve() cannot be used to reduce the capacity of the container; to that end shrink_to_fit() is provided.

Example

Main.cpp
#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);
}
}
}
Possible output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::vector reserve() method

// prism-push-types:size_type
// Non const version only
constexpr void reserve( size_type new_cap );

Increase the capacity of the vector (the total number of elements that the vector can hold without requiring reallocation) to a value that's greater or equal to new_cap. If new_cap is greater than the current capacity(), new storage is allocated, otherwise the function does nothing.

important

reserve() does not change the size of the vector.

Invalidation

If new_cap is greater than capacity(), all iterators, including the past-the-end iterator, and all references to the elements are invalidated.

Otherwise, no iterators or references are invalidated.

Parameters

  • new_cap - new capacity of the vector, in number of elements

Type requirements

  • T (the container's element type) must meet the requirements of MoveInsertable.

Return value

(none)

Complexity

At most linear in the size() of the container - O(sizes()).

Exceptions

If an exception is thrown, this function has no effect (strong exception guarantee).

If T's move constructor is not noexcept and T is not CopyInsertable into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.

Notes

Correctly using reserve() can prevent unnecessary reallocations, but inappropriate uses of reserve() (for instance, calling it before every push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and result in increased computational complexity and decreased performance.

For example, a function that receives an arbitrary vector by reference and appends elements to it should usually not call reserve() on the vector, since it does not know of the vector's usage characteristics.

When inserting a range, the range version of insert() is generally preferable as it preserves the correct capacity growth behavior, unlike reserve() followed by a series of push_back()s.

reserve() cannot be used to reduce the capacity of the container; to that end shrink_to_fit() is provided.

Example

Main.cpp
#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);
}
}
}
Possible output
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
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.