调整保留std :: vector

时间:2016-09-01 13:55:32

标签: c++ memory-management vector

我很好奇std :: vector行为,我无法在任何地方找到答案,所以......

让我们有一个奇怪的程序:

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.size(); ++i) // OK, I have noticed the mistake in the condition, I am leaving it here for educational purposes
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

内存分配方面的行为是什么?在预期的内存保留时只有一个分配,或者调整大小会清除它不需要的内存吗?

4 个答案:

答案 0 :(得分:1)

对于初学者来说,这个循环将永远不会执行

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.size(); ++i)
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

因为最初矢量的大小等于0。

也许你的意思是以下

std::vector<int> vec;
vec.reserve(5);
for(int i = 0; i < vec.capacity(); ++i)
{
    vec.resize(vec.size() + 1);
    vec[i] = 42;
}

在这种情况下,不会重新分配矢量。:)

这是一个示范程序

#include <iostream>
#include <vector>

int main()
{
    const size_t N = 5;

    std::vector<int> v;
    v.reserve( N );

    std::vector<int>::size_type i = 0;

    do
    {
        v.resize( v.size() + 1);
        std::cout << v.capacity() << '\t' << v.data() << std::endl;
    } while ( ++i < v.capacity() );

    return 0;
}

它的输出可能看起来像

5   0x824da10
5   0x824da10
5   0x824da10
5   0x824da10
5   0x824da10

答案 1 :(得分:1)

reserve方法实际上做的是:

  

请求vector capacity至少足以包含n元素。

     
      
  • 如果n大于当前vector capacity,则该函数会使容器重新分配其存储空间,将其容量增加到n(或更大)。

  •   
  • 在所有其他情况下,函数调用不会导致重新分配,并且向量容量不受影响。

  •   
  • 此功能对vector size无效,无法改变其元素。

  •   

因此,首先,vec.reserve(5);将为5元素分配内存。 (但矢量大小仍为0

然后,在内部循环中,您正在调用vec.resize(vec.size() + 1);,让我们先来看看,这个函数做了什么:

resize实际做的是:

  

调整容器大小,使其包含n个元素。

     
      
  • 如果n小于当前容器size,则内容将缩减为其第一个n元素,将其删除(并销毁它们)。

  •   
  • 如果n大于当前容器大小<​​/ em>,则会通过在最后插入所需数量的元素来扩展内容,以达到大小n。如果指定了val,则新元素将初始化为val的副本,否则会对其进行值初始化。

  •   
  • 如果n也大于当前容器容量,则会自动重新分配已分配的存储空间。

  •   
  • 请注意,此函数通过插入或删除容器中的元素来更改容器的实际内容。

  •   

在您的情况下,循环中的程序始终传递n,该capacity低于vec size ,因此,没有内存分配将执行,只会更改 .table-responsive { overflow-x: auto; min-height: .01% } .table-responsive > .table { margin-bottom: 0; } .table-responsive > .table > thead > tr > th, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > td { white-space: nowrap } .table-responsive > .table-bordered { border: 1px solid #ccc; border-collapse: collapse; } .table-responsive tr, .table-responsive td, .table-responsive th{ border: 1px solid #ccc; padding:5px } 属性。

答案 2 :(得分:0)

reserve分配空间以容纳所请求的项目数。 resize告诉向量当前容器中有多少项。

因此,如果您保留较少,则使用resize指定将进行分配。如果您预留的余额超过调整大小,则后续调整大小不需要额外分配。

答案 3 :(得分:0)

vec.size()开头为0。 vec.reserve(5)将为至少5个元素分配空间。你的循环将什么都不做。

但是,让我们假设您打算循环到5。只有预留调用才会为向量分配更多内存。循环中的大小调整,因为它们小于或等于向量的容量,只会在已分配的空间中构造新元素。