Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

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?

like image 416
weberc2 Avatar asked Dec 06 '25 14:12

weberc2


2 Answers

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.

like image 116
mfontanini Avatar answered Dec 08 '25 03:12

mfontanini


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

like image 29
Walter Avatar answered Dec 08 '25 03:12

Walter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!