Shibli
Shibli

Reputation: 6149

capacity of the vector changes after push_back()

Could someone explain why I do not get the same outputs?

main.cpp:

#include <iostream>
#include <vector>

using namespace std;

struct Cell
{
    vector<int> vtx;
};

int main()
{
    vector <Cell> cells;
    Cell tmp;
    tmp.vtx.reserve(5);
    cells.push_back (tmp);
    cout << tmp.vtx.capacity() << endl;
    cout << cells[0].vtx.capacity() << endl;
    return 0;
}

Output:

5
0

Upvotes: 9

Views: 684

Answers (1)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385405

Because taking a vector A and copying it to vector B does not guarantee that vector B will have the same capacity as vector A. Typically, the new vector will allocate only enough memory to hold the elements being copied into it.

In fact, there's an old trick that makes use of this, called the reduce-capacity trick:

int main()
{
   vector<int> v { 1,2,3,4,5 };
   v.clear();                   // capacity still non-zero

   vector<int>(v).swap(v);      // capacity now zero (maybe)
}

… though, technically, whether this actually works is entirely implementation-dependent.

If you move the vector in, rather than copying it, then there are no re-allocations, the buffer is actually the same buffer, and the capacity does not change:

#include <iostream>
#include <vector>

using namespace std;

struct Cell
{
    vector<int> vtx;
};

int main()
{
    vector <Cell> cells;
    Cell tmp;
    tmp.vtx.reserve(5);
    cout << tmp.vtx.capacity() << endl;
    cells.push_back (std::move(tmp));
    cout << cells[0].vtx.capacity() << endl;
    return 0;
}

// 5
// 5

(Notice that I had to move the first cout call to before the move, otherwise I'd be couting something that is in an unknown state.)

Upvotes: 16

Related Questions