0

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?

Rogério Dec
  • 801
  • 8
  • 31
  • 5
    do `obj.vetint.clear();` inside the `i` loop. Or move `classe obj;` to be inside the `i` loop. – M.M May 29 '18 at 02:52

3 Answers3

4

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);
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

The issue is that nothing makes obj.vetint empty after your first push_backs. Tighten obj's scope to the 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);
}

You could also explicitly erase the contents of obj.vetint (obj.vetint.clear()), so take your pick. Tightening scope is generally preferred, but there'd be a slight performance boost in this scenario if you clear (you'll avoid reallocating memory each loop iteration).

Stephen Newell
  • 7,330
  • 1
  • 24
  • 28
1

In the for loop inside another for loop you are inserting integer values in to a vector.

First time it will insert {100, 200, 300} then c becomes equal to 3 . it exits the inner for loop. i becomes 2 and then comes to inner for loop. c becomes 0 . again you are inserting values in to the same vector. So the vector values will become { 100, 200, 300, 100, 200, 300} . You have to clear the vector list by calling vectorname.clear() before incrementing i value.