Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 540
Shibli Avatar asked Jul 09 '14 17:07

Shibli


1 Answers

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

like image 115
Lightness Races in Orbit Avatar answered Sep 30 '22 04:09

Lightness Races in Orbit