weberc2
weberc2

Reputation: 7908

C++ Member Variable value changes based on whether or not it is printed out

I have a class ZoneDeVie containing a vector of vectors of Bacterie*. The Bacterie class contains an int value energie (set to 10 by default) and a toString() function which prints the value. In the ZoneDeVie constructor, I build the 2D table, populating each cell with a default instance of a Bacterie. Then, in my main method, I'm testing by printing the toString() of the last Bacterie in the table. For some reason, it returns a random, obnoxiously-large int (usually something like: 3753512); however, if I make a call to the Bacterie's toString() method in the constructor of ZoneDeVie, the main method will print out correctly.

#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

class Bacterie {
public:
    Bacterie() { this->energie = 10; }
    string toString() {
        stringstream ss;
        ss << "Energie: " << this->energie;
        return ss.str();
    }
protected:
    int energie;
};

class ZoneDeVie {
public:
    ZoneDeVie(int width, int height) {
        Bacterie* bac = new Bacterie();

        // without this [following] line, the call to `toString`
        // in the main method will return an obnoxiously-large value
        //bac->toString();
        for (int i=0; i<height; i++) {
            vector<Bacterie*> bacvec = vector<Bacterie*>();
            this->tableau.push_back(bacvec);
            for (int j=0; j<width; j++) {
                this->tableau[i].push_back(bac);
            }
        }
    }
    vector<vector<Bacterie*> > tableau;
};

int main(int argc, char *argv[]) {
    int x,y;
    x = 9; y = 39;
    ZoneDeVie zdv = ZoneDeVie(10,40);
    cout << "zdv(" << x << "," << y << ") = " << zdv.tableau[x][y]->toString();

    return 0;
}

output (with a call to "toString()" in ZoneDeVie's constructor): zdv(9,39) = Energie: 10

output (w/o a call to "toString()" in ZoneDeVie's constructor): zdv(9,39) = Energie: 4990504

Why in the world do I need to call my toString() method before calling it in the main method in order for it to behave as expected?

Upvotes: 3

Views: 382

Answers (2)

mfontanini
mfontanini

Reputation: 21900

The end condition in your for loops are swapped. You should first iterate through width and then through height:

class ZoneDeVie {
public:
    ZoneDeVie(int width, int height) {
        Bacterie* bac = new Bacterie();

        for (int i=0; i<width; i++) {
            vector<Bacterie*> bacvec = vector<Bacterie*>();
            this->tableau.push_back(bacvec);
            for (int j=0; j<height; j++) {
                this->tableau[i].push_back(bac);
            }
        }
    }
    vector<vector<Bacterie*> > tableau;
};

This compiles and provides the correct output.

Upvotes: 1

Walter
Walter

Reputation: 45434

There are several issues with this code.

  1. It's not clear what the default constructor of Bacterie does.

  2. It's not clear what ZoneDeVie::tableau is and how the local vector bacvec is used.

  3. It's not clear how the copy constructor and operator= for class ZoneDeVie are defined (both are used in main()).

  4. It seems that all entries in your table are initialised with a pointer to the same Bacterie bac

Upvotes: 1

Related Questions