0

I'm trying to construct a two-dimensional boolean array with a class I've created called Grid. The Grid object is a private member class of another class called GameOfLife. Whenever I create a GameOfLife object with the parameters belove, the Grid object first gets created with the default constructor, then it gets created again with the constructor with parameters, and then for some reason Grid's deconstructor runs and deletes everything ? I'm really out of ideas :p I'm running MinGW GCC on Eclipse Luna.

Main.cpp

const int HEIGHT = 25;
const int WIDTH = 25;
#include <iostream>
#include "GameOfLife.h"

int main(int argc, const char * argv[]) {
    GameOfLife game = GameOfLife(HEIGHT, WIDTH, false);
    game.play();
    return 0;
}

Grid.h

#ifndef __Game_Of_Life__Grid__
#define __Game_Of_Life__Grid__

#include <stdio.h>

class Grid {
public:
    Grid(int y, int x, bool state);
    Grid();
    void allocate(int x, int y, bool state);
    void deallocate();
    void set(int x, int y, bool state);
    bool get(int x, int y);
    void setAll(bool state);
    void switchBoards();
    ~Grid();
private:
    bool ** oldGeneration;
    bool ** newGeneration;
    int height;
    int width;
};
#endif /* defined(__Game_Of_Life__Grid__) */

Grid.cpp

#include "Grid.h"

Grid::Grid(int y, int x, bool state) {
    allocate(x, y, state);
}
void Grid::allocate(int x, int y, bool state) {
    height = y;
    width = x;
    oldGeneration = new bool*[height];
    newGeneration = new bool*[height];
    for (int i = 0; i < height; i++) {
        oldGeneration[i] = new bool[width];
        newGeneration[i] = new bool[width];
    }
}
Grid::~Grid() {
    deallocate();
}
void Grid::switchBoards() {
    bool ** temp = oldGeneration;
    oldGeneration = newGeneration;
    newGeneration = temp;
    delete temp;
}  
bool Grid::get(int x, int y) {
    return oldGeneration[y][x];
} 
void Grid::set(int x, int y, bool state) {
    newGeneration[y][x] = state;
}  
void Grid::deallocate() {
    if (oldGeneration != NULL || newGeneration != NULL) {
        for (int i = 0; i < height; i++) {
                delete [] oldGeneration[i];
                delete [] newGeneration[i];
        }
        delete [] oldGeneration;
        delete [] newGeneration;
    }
    return;
}
Grid::Grid() {
    oldGeneration = NULL;
    newGeneration = NULL;
    width = 0;
    height = 0;
}
void Grid::setAll(bool state) {

    for (int i = 0; i < height; i++) {
        for (int n = 0; n < width; n++) {
            newGeneration[i][n] = state;
        }
    }
}

GameOfLife.h

#ifndef __Game_Of_Life__GameOfLife__
#define __Game_Of_Life__GameOfLife__

#include <stdio.h>
#include "Grid.h"
#include <iostream>


class GameOfLife {
private:
    Grid board;

public:

    GameOfLife(int y, int x, bool state);
    GameOfLife();
    ~GameOfLife();
    void play();
    void welcome();
    void makeBoard();
    void updateBoard();
    int findAliveNeighbours(int x, int y);
};

#endif /* defined(__Conway__GameOfLife__) */

GameOfLife.cpp

#include "GameOfLife.h"
const int WIDTH = 100;
const int HEIGHT= 75;



GameOfLife::GameOfLife(int y, int x, bool state) {
    board = Grid(y, x, state);

}
GameOfLife::GameOfLife() {
    board = Grid();
}

GameOfLife::~GameOfLife() {
    board.deallocate();
}
void GameOfLife::play() {

    welcome();
    makeBoard();

    for (int i = 0; i < HEIGHT; i++) {
        for (int n = 0; n < WIDTH; n++) {
            std::cout << board.get(n,i) << " ";
        }
        std::cout << std::endl;
    }
    updateBoard();
    std::cout << std::endl;
    for (int i = 0; i < HEIGHT; i++) {
        for (int n = 0; n < WIDTH; n++) {
            std::cout << board.get(n,i) << " ";
        }
        std::cout << std::endl;
    }

}
void GameOfLife::makeBoard() {
    int x1,x2,x3,x4, y1,y2,y3,y4;
    x1 = 10; y1 = 10;
    x2 = 10; y2 = 11;
    x3 = 10; y3 = 12;
    x4 = 11; y4 = 13;
    int x5 = 0; int y5 = 0;
    board.set(x1, y1, true);
    board.set(x2, y2, true);
    board.set(x3, y3, true);
    board.set(x4, y4, true);
    board.set(x5, y5, true);
}
void GameOfLife::welcome() {

        std::cout << "Welcome to Conway's Game Of Life"
                  << std::endl;
}
user1784297
  • 103
  • 12

1 Answers1

2
GameOfLife::GameOfLife(int y, int x, bool state) {

    // board is a member variable that gets initialized
    // with the default constructor.
    // Then it gets replaced by assignment with a different
    // Grid object. The temporary object gets deleted at
    // the end of the line.
    board = Grid(y, x, state);
}

Change the implementation to:

GameOfLife::GameOfLife(int y, int x, bool state) : board(y, x, state) {}

Similarly, change the default constructor to:

GameOfLife::GameOfLife() {}

The more important problem that needs to be fixed is that you are breaking The Rule of Three.

You need to add proper implementations of the copy constructor and the copy assignment opertor in Grid.

The other, and better, option is to change the internal data of Grid to

std::vector<std::vector<bool>> oldGeneration;
std::vector<std::vector<bool>> newGeneration;

Then, the compiler generated copy constructor and copy assignment operator will be good enough.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Thank you! I had been playing with that set up, but seems I couldn't get it right. On a sidenote, without having to open a whole new question; any idea why my get-function is returning int values? – user1784297 Mar 11 '15 at 04:13
  • The return type of `Grid::get()` is `bool`. It should return `true` or `false`. I don't know why it would return `int` values. I also noticed that you haven't used the value of `state` in `Grid::allocate()`. – R Sahu Mar 11 '15 at 04:19
  • Yeah, it's not there at the moment because I was testing something earlier. But, yeah, the array is acting very strange. Everytime I run it, it either outputs some speficic numbers over and over again, but now it just crashes when I get to the first get-function. – user1784297 Mar 11 '15 at 04:26
  • This sweeps the problem under the carpet, but doesn't fix it. The real problem is that the class breaks the [Rule of Three](http://stackoverflow.com/questions/4172722) and will explode if copied. – Mike Seymour Mar 11 '15 at 08:26
  • @MikeSeymour, agree with that assessment. – R Sahu Mar 11 '15 at 15:14