Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/container/vector/reserve"

From cppreference.com
< cpp‎ | container‎ | vector
m (added link to cs translation)
((previous edit comment meant to say "for vector::reserve"). Collapsing the template here since it's only used once.)
Line 1: Line 1:
{{include page|cpp/container/reserve|vector}}
+
{{cpp/container/vector/title | reserve}}
 +
{{cpp/container/vector/navbar}}
 +
{{dcl begin}}
 +
{{dcl |
 +
void reserve( size_type new_cap );
 +
}}
 +
{{dcl end}}
 +
 
 +
Increase the capacity of the vector to a value that's greater or equal to {{tt|new_cap}}. If {{tt|new_cap}} is greater than the current {{lc|capacity()}}, new storage is allocated, otherwise the method does nothing.
 +
 
 +
{{cpp/container/note iterator invalidation|vector|reserve}}
 +
 
 +
===Parameters===
 +
{{par begin}}
 +
{{par | new_cap | new capacity of the vector }}
 +
{{par hreq}}
 +
{{par req concept | T | MoveInsertable}}
 +
{{par end}}
 +
 
 +
===Return value===
 +
(none)
 +
 
 +
===Exceptions===
 +
* {{lc|std::length_error}} if {{c|new_cap > max_size()}}.
 +
* any exception thrown by {{tt|Allocator::allocate()}} (typically {{lc|std::bad_alloc}})
 +
 
 +
If an exception is thrown, this function has no effect ([[cpp/language/exceptions|strong exception guarantee]]).
 +
{{rev begin}}
 +
{{rev | since=c++11 |
 +
If {{tt|T}}'s move constructor is not {{c|noexcept}} and T is not {{concept|CopyInsertable}} into {{tt|*this}}, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified.}}
 +
{{rev end}}
 +
 
 +
===Complexity===
 +
At most linear in the {{lc|size()}} of the container.
 +
 
 +
===Notes===
 +
{{lc|reserve()}} cannot be used to reduce the capacity of the container, to that end {{lc|shrink_to_fit()}} is provided.
 +
 
 +
Correctly using {{lc|reserve()}} can prevent unnecessary reallocations, but inappropriate uses of {{lc|reserve()}} (for instance, calling it before every {{lc|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.
 +
 
 +
===Example===
 +
{{example
 +
|code=
 +
#include <cstddef>
 +
#include <new>
 +
#include <vector>
 +
#include <iostream>
 +
 
 +
// 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);
 +
        std::cout << "allocating " << n << " bytes\n";
 +
        return static_cast<Tp*>(::operator new(n));
 +
    }
 +
    void deallocate(Tp* p, std::size_t n) {
 +
        std::cout << "deallocating " << n*sizeof*p << " bytes\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()
 +
{
 +
    int sz = 100;
 +
    std::cout << "using reserve: \n";
 +
    {
 +
        std::vector<int, NAlloc<int>> v1;
 +
        v1.reserve(sz);
 +
        for(int n = 0; n < sz; ++n)
 +
            v1.push_back(n);
 +
    }
 +
    std::cout << "not using reserve: \n";
 +
    {
 +
        std::vector<int, NAlloc<int>> v1;
 +
        for(int n = 0; n < sz; ++n)
 +
            v1.push_back(n);
 +
    }
 +
}
 +
|p=true
 +
|output=
 +
using reserve:
 +
allocating 400 bytes
 +
deallocating 400 bytes
 +
not using reserve:
 +
allocating 4 bytes
 +
allocating 8 bytes
 +
deallocating 4 bytes
 +
allocating 16 bytes
 +
deallocating 8 bytes
 +
allocating 32 bytes
 +
deallocating 16 bytes
 +
allocating 64 bytes
 +
deallocating 32 bytes
 +
allocating 128 bytes
 +
deallocating 64 bytes
 +
allocating 256 bytes
 +
deallocating 128 bytes
 +
allocating 512 bytes
 +
deallocating 256 bytes
 +
deallocating 512 bytes
 +
}}
 +
 
 +
===See also===
 +
{{dsc begin}}
 +
{{dsc inc | cpp/container/dsc capacity |vector}}
 +
{{dsc inc | cpp/container/dsc max_size |vector}}
 +
{{dsc inc | cpp/container/dsc resize |vector}}
 +
{{dsc inc | cpp/container/dsc shrink_to_fit |vector}}
 +
{{dsc end}}
  
 
[[cs:cpp/container/vector/reserve]]
 
[[cs:cpp/container/vector/reserve]]

Revision as of 03:40, 10 June 2017

 
 
 
 
void reserve( size_type new_cap );

Increase the capacity of the vector 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 method does nothing.

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

Contents

Parameters

new_cap - new capacity of the vector
Type requirements

Template:par req concept

Return value

(none)

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 Template:concept into *this, vector will use the throwing move constructor. If it throws, the guarantee is waived and the effects are unspecified. (since C++11)

Complexity

At most linear in the size() of the container.

Notes

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

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.

Example

#include <cstddef>
#include <new>
#include <vector>
#include <iostream>
 
// 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);
        std::cout << "allocating " << n << " bytes\n";
        return static_cast<Tp*>(::operator new(n));
    }
    void deallocate(Tp* p, std::size_t n) {
        std::cout << "deallocating " << n*sizeof*p << " bytes\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()
{
    int sz = 100;
    std::cout << "using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        v1.reserve(sz);
        for(int n = 0; n < sz; ++n)
            v1.push_back(n);
    }
    std::cout << "not using reserve: \n";
    {
        std::vector<int, NAlloc<int>> v1;
        for(int n = 0; n < sz; ++n)
            v1.push_back(n);
    }
}

Possible output:

using reserve: 
allocating 400 bytes
deallocating 400 bytes
not using reserve: 
allocating 4 bytes
allocating 8 bytes
deallocating 4 bytes
allocating 16 bytes
deallocating 8 bytes
allocating 32 bytes
deallocating 16 bytes
allocating 64 bytes
deallocating 32 bytes
allocating 128 bytes
deallocating 64 bytes
allocating 256 bytes
deallocating 128 bytes
allocating 512 bytes
deallocating 256 bytes
deallocating 512 bytes

See also

returns the number of elements that can be held in currently allocated storage
(public member function) [edit]
returns the maximum possible number of elements
(public member function) [edit]
changes the number of elements stored
(public member function) [edit]
reduces memory usage by freeing unused memory
(public member function) [edit]