命名空间
变体
操作

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

来自 cppreference.cn
< cpp‎ | 容器‎ | vector
 
 
 
 
void reserve( size_type new_cap );
(constexpr since C++20)

增加 vector 的容量(vector 可以容纳而无需重新分配的元素总数)到一个大于或等于 new_cap 的值。如果 new_cap 大于当前的 capacity(),则会分配新的存储空间,否则该函数不执行任何操作。

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

如果 new_cap 大于 capacity(),则所有迭代器(包括 end() 迭代器)以及对元素的所有引用都将失效。否则,迭代器或引用均不会失效。

在调用 reserve() 之后,除非插入操作会导致 vector 的大小大于 capacity() 的值,否则插入操作将不会触发重新分配。

内容

[编辑] 参数

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

[编辑] 返回值

(无)

[编辑] 异常

如果抛出异常,则此函数无效(强异常安全保证)。

如果 T 的移动构造函数不是 noexcept 且 T 不是 CopyInsertable*this,vector 将使用可能抛出异常的移动构造函数。如果它抛出异常,则保证被放弃,并且效果是未指定的。

(C++11 起)

[编辑] 复杂度

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

[编辑] 注释

正确使用 reserve() 可以防止不必要的重新分配,但不恰当地使用 reserve()(例如,在每次 push_back() 调用之前调用它)实际上可能会增加重新分配的次数(通过导致容量线性而不是指数增长),并导致计算复杂性增加和性能下降。例如,接收对任意 vector 的引用的函数,并向其追加元素,通常应在 vector 上调用 reserve(),因为它不知道 vector 的使用特性。

当插入一个范围时,通常首选 insert() 的范围版本,因为它保留了正确的容量增长行为,这与 reserve() 后跟一系列 push_back() 不同。

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

[编辑] 示例

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

可能的输出

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++ 标准。

DR 应用于 已发布行为 正确行为
LWG 329 C++98 如果插入操作使 vector 的大小大于
最近一次调用 reserve() 中指定的大小,则可能会触发重新分配
最近一次调用 reserve() 中指定的大小,则可能会触发重新分配
仅当 vector 的大小
变得大于 capacity() 时才触发
变得大于 capacity() 时才触发
LWG 2033 C++11 T 不需要是 MoveInsertable 需要

[编辑] 参见

返回当前已分配存储空间中可以容纳的元素数量
(公共成员函数) [编辑]
返回最大可能的元素数量
(公共成员函数) [编辑]
更改存储的元素数量
(公共成员函数) [编辑]
通过释放未使用的内存来减少内存使用量
(公共成员函数) [编辑]