-2

I am making conway's game of life. I have two classes, one for the plane of cells, and another for the cells. The cells are like a 2d linked list with 4 pointers per cell pointing to the vertical and horizontal neighbors. When trying to access any of the cell pointers to other cells, or the alive member the program crashes.

my code

//game.h
#ifndef GAME_H_
#define GAME_H_
#include <iostream>
class cell{
    public:
        bool alive;
        cell* top;
        cell* bot;
        cell* lef;
        cell* rig;
        cell(){
            alive = false;
            top = bot = lef = rig = nullptr;
        }
        cell* link(char);
        int alive_neighbors();
        void link_right(cell*);
        void link_down(cell*);
        void refresh_cell();

};

class field{
    public:
        int size;
        cell * origin;
        bool ** new_state;
        cell *** fi;
        field(int a);
        ~field();

};

#endif

and

//game.cpp
#include <iostream>
#include "game.h"

int cell::alive_neighbors(){
    int num = 0;
    (this->top)?((this->top->alive)?(++num):(num)||((this->top->rig)?((this->top->rig->alive)?(num++):(num)):(num))):(num);
    (this->bot)?((this->bot->alive)?(++num):(num)||((this->bot->lef)?((this->bot->lef->alive)?(num++):(num)):(num))):(num);
    (this->rig)?((this->rig->alive)?(++num):(num)||((this->rig->bot)?((this->rig->bot->alive)?(num++):(num)):(num))):(num);
    (this->lef)?((this->lef->alive)?(++num):(num)||((this->lef->bot)?((this->lef->bot->alive)?(num++):(num)):(num))):(num);
    return num;
}

void cell::link_right(cell* linkee){
    this->rig = linkee;
    linkee->lef = this;
}

void cell::link_down(cell* linkee){
    this->bot = linkee;
    linkee->top = this;
}

field::field(int a){
    size = a;
    for (int i= 0; i < size; i++){
        fi[i] = new cell*[size];
        for (int j = 0; j < size; j++){
            fi[i][j] = new cell;                
        }
    }
    for (int i = 0; i < size; i++){
        for (int j = 0; j < size -1; j++){
            this->fi[i][j]->link_right(this->fi[i][j+1]);
            this->fi[j][i]->link_down(this->fi[j+1][i]);
        }
    }
    origin = fi[0][0]
}

field::~field(){
    for (int i = size -1; i >= 0; i--){
        for (int j = size -1;j >= 0; j--){
            delete fi[i][j];
        }
        delete fi[i];
    }
}

Error:

#include "game.h"
int main(){
    field game(10);
    std::cout << game.origin->alive << std::endl; //compiles but crashes :(
    std::cout << game.origin->rig << std::endl; //also compiles and crashes without giving adress.
    std::cout << game.fi[0][0]->alive; //even directly accessing the cell compiles and crashes.
}
Anandamide
  • 243
  • 1
  • 15
  • 4
    You allocate `fi[i]`, but where do you initialize and allocate memory for `fi` itself? And do you really need a matrix of *pointers*? And what about a vector of vectors instead? – Some programmer dude Aug 25 '15 at 02:31
  • It seemed easier to have each cell in the array stored as a pointer for the linking of the cells. The cell pointers in each cell can be set directly from the cell pointers in the field array. – Anandamide Aug 25 '15 at 02:39
  • I responded and then used his answer to fix my program. His initial inquiry was obviously rhetorical since i had not allocated `fi` anywhere in the code sample I provided. Anyways, do you need to be rude about it, what is the issue with using as much indirection as I please in my own project? – Anandamide Aug 25 '15 at 03:32
  • 2
    OP just asked a question.. Everyone has coded pointer spaghetti sometime ... Also why the downvotes to the question guys? –  Aug 25 '15 at 03:55

1 Answers1

1

The problem was with game.cpp try this code

//game.cpp
#include <iostream>
#include "stackoverflow.hpp"

int cell::alive_neighbors(){
    int num = 0;
    (this->top)?((this->top->alive)?(++num):(num)||((this->top->rig)?((this->top->rig->alive)?(num++):(num)):(num))):(num);
    (this->bot)?((this->bot->alive)?(++num):(num)||((this->bot->lef)?((this->bot->lef->alive)?(num++):(num)):(num))):(num);
    (this->rig)?((this->rig->alive)?(++num):(num)||((this->rig->bot)?((this->rig->bot->alive)?(num++):(num)):(num))):(num);
    (this->lef)?((this->lef->alive)?(++num):(num)||((this->lef->bot)?((this->lef->bot->alive)?(num++):(num)):(num))):(num);
    return num;
}

void cell::link_right(cell* linkee){
    this->rig = linkee;
    linkee->lef = this;
}

void cell::link_down(cell* linkee){
    this->bot = linkee;
    linkee->top = this;
}

field::field(int a){
    size = a;
    fi = new cell**[size];
    for (int i= 0; i < size; i++){
        fi[i] = new cell*[size];
        for (int j = 0; j < size; j++){
            fi[i][j] = new cell;                
        }
    }
    for (int i = 0; i < size; i++){
        for (int j = 0; j < size -1; j++){
            this->fi[i][j]->link_right(this->fi[i][j+1]);
            this->fi[j][i]->link_down(this->fi[j+1][i]);
        }
    }
    origin = fi[0][0];
}

field::~field(){
    for (int i = size -1; i >= 0; i--){
        for (int j = size -1;j >= 0; j--){
            delete fi[i][j];
        }
        delete fi[i];
    }
}

I do not understand why people here tend to get annoyed because the ones asking questions are not coding with the "correct" style. We all need to make mistakes and learn from them. On that note in the future when you work on another C++ project. Try using the STL containers, they will be refreshingly simple and efficient. You'll love them.

Also think of n-dimensional arrays this way. Use one * for every dimension. So an int* arr is a 1-D array and an int** arr is a 2-D array. You can switch to a cell** here since you want a 2-D array :)