Namespaces
Variants

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

From cppreference.net
void reserve ( size_type new_cap ) ;
(自 C++20 起为 constexpr)

将向量的容量(向量在不需重新分配的情况下能够容纳的元素总数)增加至大于或等于 new_cap 的值。若 new_cap 大于当前 capacity() ,则会分配新存储空间,否则该函数不执行任何操作。

reserve() 不会改变 vector 的大小。

如果 new_cap 大于 capacity() ,则所有迭代器(包括 end() 迭代器)和所有元素引用都会失效。否则,不会使任何迭代器或引用失效。

在调用 reserve() 后,插入操作将不会触发重新分配,除非插入操作会使 vector 的大小超过 capacity() 的值。

目录

参数

new_cap - 向量的新容量,以元素数量计
类型要求
-
T 必须满足 MoveInsertable * this 的要求。 (自 C++11 起)

返回值

(无)

异常

若抛出异常,则此函数不产生任何效果( 强异常保证 )。

如果 T 的移动构造函数不是 noexcept 且 T 不满足 可复制插入 * this 的要求,vector 将使用可能抛出异常的移动构造函数。若该构造函数抛出异常,则不再提供任何保证且效果是未指定的。

(C++11 起)

复杂度

最多与容器的 size() 呈线性关系。

注释

正确使用 reserve() 可以避免不必要的重新分配,但不恰当地使用 reserve() (例如在每次 push_back() 调用前都执行该操作)实际上可能增加重新分配次数(导致容量以线性而非指数方式增长),从而增加计算复杂度并降低性能。例如,一个通过引用接收任意向量并为其追加元素的函数通常 不应 对该向量调用 reserve() ,因为该函数并不了解该向量的使用特征。

在插入范围时,通常更推荐使用范围版本的 insert() ,因为它能保持正确的容量增长行为,这与先使用 reserve() 再执行一系列 push_back() 操作不同。

reserve() 不能用于缩减容器的容量;为此目的提供了 shrink_to_fit()

示例

#include <cstddef>
#include <iostream>
#include <new>
#include <vector>
// 带调试输出的最小C++11分配器
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); // 预留至少 max_elements * sizeof(int) 字节
        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);
        }
    }
}

可能的输出:

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

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时行为 正确行为
LWG 329 C++98 如果插入操作使vector的大小超过最近一次调用
reserve() 时指定的大小,则可能触发重新分配
仅当vector的大小
超过 capacity()
才会触发
LWG 2033 C++11 未要求 T 满足 MoveInsertable 要求 要求必须满足

另请参阅

返回当前分配存储空间可容纳的元素数量
(公开成员函数)
返回可能容纳的最大元素数量
(公开成员函数)
改变存储的元素数量
(公开成员函数)
通过释放未使用的内存来减少内存使用
(公开成员函数)