std::vector<T,Allocator>:: reserve
|
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 起)
|
||
返回值
(无)
异常
- 若 new_cap > max_size ( ) 则抛出 std::length_error 。
-
由
Allocator::allocate()抛出的任何异常(通常为 std::bad_alloc )。
若抛出异常,则此函数不产生任何效果( 强异常保证 )。
|
如果
|
(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
要求
|
要求必须满足 |
另请参阅
|
返回当前分配存储空间可容纳的元素数量
(公开成员函数) |
|
|
返回可能容纳的最大元素数量
(公开成员函数) |
|
|
改变存储的元素数量
(公开成员函数) |
|
|
(
DR*
)
|
通过释放未使用的内存来减少内存使用
(公开成员函数) |