Search code examples
c++vectorpush-back

vector within vector generates duplicate values in second dimension


In the example below (which can also be seen in Ideone), I have a vector of a class and inside the class I have an element also vector.

The problem is that when doing the push_back of the class, the internal vector vetint should start from the beginning again, for each push_back of the first dimension, but c++ is holding the previous values, hence the vector doubles.

#include <iostream>
#include <vector>

using namespace std;
class classe
{
public:
    int var;
    vector<int> vetint;
};


int main()
{
    vector<classe> vetor;
    classe obj;

    for (unsigned i=0; i<2 ; i++) {
        obj.var = (i+1)*10;
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }
    for (unsigned i=0; i < vetor.size() ; i++) {
        cout << "var(" << i << ") = " << vetor[i].var << endl;
        for (unsigned c=0; c < vetor[i].vetint.size() ; c++) {
            cout << "vetint(" << c << ") = " << vetor[i].vetint[c] << endl;;
        }
    }
}

It produces this result:

var(0) = 10
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
var(1) = 20
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
vetint(3) = 100
vetint(4) = 200
vetint(5) = 300

When the desired one would be:

var(0) = 10
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300
var(1) = 20
vetint(0) = 100
vetint(1) = 200
vetint(2) = 300

Why does it happen? How to solve?


Solution

  • If you unroll the first for loop, your code will be:

    classe obj;
    
    obj.var = (0+1)*10;
    for (unsigned c=0; c<3 ; c++) {
       obj.vetint.push_back((c+1)*100);
    }
    
    // obj has three elements in it.
    vetor.push_back(obj);
    
    obj.var = (1+1)*10;
    for (unsigned c=0; c<3 ; c++) {
       obj.vetint.push_back((c+1)*100);
    }
    
    // obj has six elements in it.
    vetor.push_back(obj);
    

    That explains whey the vetint of the second object in vetor has six elements.

    You can fix the problem using one of the following methods:

    Solution 1

    Moving the declaration/definition of obj inside the for loop.

    for (unsigned i=0; i<2 ; i++) {
        classe obj;
        obj.var = (i+1)*10;
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }
    

    Solution 2

    Clear the contents of obj.vetint in the loop before adding items to it.

    for (unsigned i=0; i<2 ; i++) {
        obj.vetint.clear();
        obj.var = (i+1)*10;
        for (unsigned c=0; c<3 ; c++) {
            obj.vetint.push_back((c+1)*100);
        }
        vetor.push_back(obj);
    }