resize()根据给定的大小添加/删除元素。 reserve()保留内存空间,不会重新分配内存。我的问题是,调整大小是否与向量的容量相同也只是不会增加?
要添加,会结合使用:
std::vector<X> vector;
vector.reserve(5);
vector.resize(5);
有道理吗?这是多余的吗?这里的目标是能够覆盖向量中的值,而不需要向量分配任何额外的空间。
答案 0 :(得分:4)
来自this site:
resize()
:这可让您将矢量的大小更改为您想要的任何大小。
reserve()
:这会改变矢量的容量。请注意,这不会更改向量的大小,只是更改底层缓冲区的大小,以便在缓冲区必须调整大小之前为缓冲区的扩展提供更多空间。与调用resize()
不同,这不会改变程序的行为,只会改变性能(后续使用保留空间不会对增量保留造成性能损失)。
我遇到的问题是,调整大小是否也与调整大小相同 载体的容量只会不会增加? 要添加,将结合使用:
std::vector<X> vector; vector.reserve(5); vector.resize(5);
有道理吗?这是多余的吗?
vector.reserve(5);
在这种情况下会多余。
这里的目标是能够在没有的情况下覆盖向量中的值 让矢量分配任何额外的空间。
对于此目标,它取决于您要如何覆盖值。
resize()
。push_back()
,那么reserve()
会更好,这样您就可以避免两次创建X
。请记住,用于自动预留的算法是实现定义的。有关性能方面的更多信息,请参阅here。
答案 1 :(得分:4)
我不知道您在哪里获得了有关reserve
的信息,但是如果传递给它的数字大于向量的当前容量,它会重新分配,如{ {1}}功能。
对于capacity
,需要设置元素的数量,如果容量中没有足够的空间,则还需要重新分配。
至于您的代码段:
resize
如果您想分配可能的最小量以存储5个元素,这可能是有意义的。我之所以这么说是因为std::vector<X> vector;
vector.reserve(5);
vector.resize(5);
可能会在以后有更多的添加内容中分配更多的内容(很明显,只有在请求的大小大于容量时才会发生这种情况。resize
永远不会导致如果请求的大小&lt; = capacity,则重新分配。另一方面,resize
通常只是分配足够的。允许分配更多,但我从未见过这样做的实现。
答案 2 :(得分:3)
它们之间的主要区别在于resize允许您更改大小(增加或减少),而reserve只保留系统内存。使用默认构造函数调用或基于调整大小形式的复制构造函数调整已分配内存的大小。
两者都可能导致内存重新分配。
答案 3 :(得分:3)
要扩大@ BenjaminLindley的答案,在海湾合作委员会中肯定存在差异。
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a, b;
for (std::size_t i=0; i<20; ++i)
{
a.reserve(i); a.resize(i); // a: reserve-then-resize
b.resize(i); // b: resize directly
std::cout << a.capacity() << "\t" << b.capacity() << "\n";
}
}
输出(live demo):
0 0
1 1
2 2
3 4
4 4
5 8
6 8
7 8
8 8
9 16
10 16
11 16
12 16
13 16
14 16
15 16
16 16
17 32
18 32
19 32
因此,至少对于gcc,reserve-then-resize会导致完全您要求的容量,而直接调整大小“提前计划”预期的未来分配。
答案 4 :(得分:2)
在某些实现中,resize
几乎肯定会先调用reserve
。最近实现了std::vector
的变体,下面是std::vector::reserve
的精简和注释版本...(评论是为了OP的理解) ...实际上大多数STL实现将稍微复杂一点(用于调试目的);但它的概念基本相同。
template<typename T>
void Vector<T>::reserve(SizeType sz){
//if only the new size is greater than current capacity
if(sz > m_capacity){
//allocate the new size
T* data = static_cast<T*>(SFAllocator<T>::allocate(sz));
//move all previous data
for(SizeType i=0; i < m_size; i++){
new(data+i) T(std::move(m_data[i])); //! TODO: move if only noexcept;
//call the destructor on the moved item
call_destructor(m_data[i]);
}
//deallocate formerly used memory
SFAllocator<T>::deallocate(m_data);
//reassign the capacity to the new capacity
m_capacity = sz;
m_data = data; //reassign the data pointer
//size remains the same
}
以下是std::vector::resize
的精简和注释版本。如下所示,resize
首先调用reserve
。
template<typename T>
void Vector<T>::resize(SizeType sz){
// resize it to fit at least fit to "sz"
reserve(sz);
//if higher size is requested
if(sz > m_size)
//default construct the remainder of the new uninitialized memory
for(SizeType i= m_size; i < sz; i++)
new(m_data+i) T{}
//if the container size is to get smaller
else
for(SizeType i=sz; i<m_size; i++)
call_destructor(m_data[i]); //delete the elements at indexes above "sz"
m_size = sz; //change container size.
}