I have a lil' segmentation fault problem. My program crash instantly when i specify a different line and columns number, and when i specify a square board (same Nbline and Nbcolumns), i crash when calling the print function with tmp pointer.
I'll show my main(), Board class and constructor, my Graph class, constructor and addNode method, and my print method (which is not in any class for the moment but will be as soon as this bug is solved !)
int main()
{
int lines, columns;
Play game; // Déclaration à refaire proprement avec new() et un constructeur
Play& jeu = game;
srand(time(NULL));
cout << "Random board \nLines : ";
cin >> lines;
cout << "\n Columns : ";
cin >> columns;
Board* randomTab = new Board(lines, columns, jeu);
Board temporary = *randomTab;
Board* tmp = NULL;
Graph tree(randomTab);
print(randomTab); // this print works perfectly fine !
cout << "________________" << endl;
tree.CreateAllChildren(jeu); // create every possible children for the current board
vector<Graph*> children = tree.getchildren();
for(vector<Graph*>::iterator itr = children.begin(); itr != children.end(); ++itr)
{
tmp = (*itr)->gettab();
print(tmp); // this print fail.
// trace(temporary);
}
class Board
{
private:
int** plato;
int nbline;
int nbcolumn;
Position emptyspot;
public:
[...] // bunch of unused in this use case constructors, destructors etc...
Board(int, int, Play&); // constructor in this use case
void setValue(Position&, int);
void setNbline(int m);
void setNbcolumn(int n);
int getValue(Position&);
int** getPlato();
int getNbline();
int getNbcolumn();
int getEmptyline();
int getEmptycolumn();
void setEmptySpot(Position&);
Position& getEmptySpot();
[...]
};
Board::Board(int m, int n, Play& jeu) : plato(new int*[m]), nbline(m), nbcolumn(n), emptyspot(n-1,m-1)
{
int x(1);
for (int i = 0; i < m; ++i)
{
plato[i] = new int[n];
for(int j = 0; j < n; ++j)
{
plato[i][j] = x;
x++;
}
}
plato[m-1][n-1]=0;
x=0;
while (x!=1000)
{
int numbers[] = { UP, DOWN, LEFT, RIGHT };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
jeu.moves(*this, randomNumber);
x++;
}
}
class Play
{
/// nothing really relevant in the use case except the move methods
private:
[...]
public:
void moves(Board*);
bool moves(Board*, int);
bool moves(Board&, int); // overload to use move in Board constructor with *this
};
bool Play::moves(Board& tab, int code)
{
Position temporary(0,0);
Position& tmp = temporary;
bool control(false);
switch(code)
{
case LEFT :
if(tab.getEmptycolumn()>0)
{
tmp.setposition(tab.getEmptyline(),tab.getEmptycolumn()-1); // on place la destinsation du vide
tab.setValue(tab.getEmptySpot(),tab.getValue(tmp)); // le vide vaut la valeur de sa destination
tab.setEmptySpot(tmp); // actualisation du vide
control = true;
return control;
}
break;
case UP :
if(tab.getEmptyline() > 0)
{
tmp.setposition(tab.getEmptyline()-1,tab.getEmptycolumn()); // on place la destinsation du vide
tab.setValue(tab.getEmptySpot(),tab.getValue(tmp)); // le vide vaut la position de la case qui va bouger
tab.setEmptySpot(tmp); // actualisation du vide
control = true;
return control;
}
break;
case RIGHT :
if(tab.getEmptycolumn() < tab.getNbcolumn()-1)
{
tmp.setposition(tab.getEmptyline(),tab.getEmptycolumn()+1); // on place la destinsation du vide
tab.setValue(tab.getEmptySpot(),tab.getValue(tmp)); // le vide vaut la position de la case qui va bouger
tab.setEmptySpot(tmp); // actualisation du vide
control = true;
return control;
}
break;
case DOWN :
if(tab.getEmptyline() < tab.getNbline()-1)
{
tmp.setposition(tab.getEmptyline()+1,tab.getEmptycolumn()); // on place la destinsation du vide
tab.setValue(tab.getEmptySpot(),tab.getValue(tmp)); // le vide vaut la position de la case qui va bouger
tab.setEmptySpot(tmp); // actualisation du vide
control = true;
return control;
}
break;
default :
cerr << "Mouvement impossible " << endl;
break; // erreur
}
return control;
}
class Graph
{
private:
Graph* parent;
vector<Graph*> children;
Board* tab;
public:
Graph(Board*);
Graph(Board*, Graph*);
Graph(const Graph&);
~Graph();
void AddNode(Board*);
void CreateAllChildren(Play&); // just a call of AddNode each time Play.move with a direction return true.
Graph& operator=(Graph);
vector<Graph*>& getchildren();
Graph* getparent();
Board* gettab();
};
void Graph::AddNode(Board* tablo)
{
Graph* newChild = new Graph(tablo, this);
children.push_back(newChild);
}
void print(Board* tab)
{
Position pos(0,0);
Position& p = pos;
for (int i = 0; i < tab->getNbline(); i++)
{
for(int j = 0; j < tab->getNbcolumn(); j++)
{
p.setposition(i,j);
if(i == tab->getEmptyline() && j == tab->getEmptycolumn())
{
cout << setw(tab->getNbcolumn()) << tab->getValue(p);
if (j == tab->getNbcolumn()-1)
{
cout << endl;
}
}
else
{
/// Call stack point at this line
cout << setw(tab->getNbcolumn()) << tab->getValue(p);
if (j == tab->getNbcolumn()-1)
{
cout << endl;
}
}
}
}
cout << endl;
return;
}
Any idea of what is wrong ? I thought my code was correct :( ask if you don't have enough elements to find the problem