std::vector<T,Allocator>::reserve
void reserve( size_type new_cap ); |
(constexpr since C++20) | |
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()
reserve()
does not change the size of the vector.
If new_cap is greater than capacity(), all iterators (including the end()
After a call to reserve()
, insertions will not trigger reallocation unless the insertion would make the size of the vector greater than the value of capacity()
Parameters
new_cap | - | new capacity of the vector, in number of elements |
Type requirements | ||
-
T must meet the requirements of MoveInsertable into *this. (since C++11)
|
Return value
(none)
Exceptions
- std::length_error if new_cap > max_size()
- Any exception thrown by
Allocator::allocate()
(typically std::bad_alloc).
If an exception is thrown, this function has no effect (strong exception guarantee).
If |
(since C++11) |
Complexity
At most linear in the size() of the container.
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()
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()
reserve()
cannot be used to reduce the capacity of the container; to that end shrink_to_fit() is provided.
Example
#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
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
LWG 329 | C++98 | reallocation might be triggered if an insertion makes the size of the vector greater than the size specified in the most recent call to reserve()
|
only triggers if the size of the vector becomes greater than capacity() |
LWG 2033 | C++11 | T was not required to be MoveInsertable
|
required |
See also
returns the number of elements that can be held in currently allocated storage (public member function) |
|
returns the maximum possible number of elements (public member function) |
|
changes the number of elements stored (public member function) |
|
(DR*)
|
reduces memory usage by freeing unused memory (public member function) |