C ++标准向量resize()函数

时间:2016-05-12 19:57:10

标签: c++ resize stdvector

resize()根据给定的大小添加/删除元素。 reserve()保留内存空间,不会重新分配内存。我的问题是,调整大小是否与向量的容量相同也只是不会增加?

要添加,会结合使用:

 std::vector<X> vector;
 vector.reserve(5);
 vector.resize(5); 

有道理吗?这是多余的吗?这里的目标是能够覆盖向量中的值,而不需要向量分配任何额外的空间。

5 个答案:

答案 0 :(得分:4)

来自this site

  • resize():这可让您将矢量的大小更改为您想要的任何大小。
    • 它将使用元素填充底层缓冲区。
  • reserve():这会改变矢量的容量。请注意,这不会更改向量的大小,只是更改底层缓冲区的大小,以便在缓冲区必须调整大小之前为缓冲区的扩展提供更多空间。与调用resize()不同,这不会改变程序的行为,只会改变性能(后续使用保留空间不会对增量保留造成性能损失)。
    • 它不会限制缓冲区的大小。如果缓冲区空间不足,它将根据需要自动重新分配。

enter image description here

  

我遇到的问题是,调整大小是否也与调整大小相同   载体的容量只会不会增加?   要添加,将结合使用:

 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.
}