0

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

Csi
  • 526
  • 3
  • 22
  • Did you step through the code with the debugger to make sure you are getting good data? – NathanOliver Apr 28 '15 at 14:29
  • @NathanOliver. I'm going to see it with debugger but i'm not familiar with it. My question have been classified. "Duplicate". But the link doesn't help me much... What about The Rule of Three ? I got a constructor, copy constructor and destructor for both my class Board and Graph... Is that what they mean ? – Csi Apr 28 '15 at 16:24
  • @Borgleader It's not a rule of 3 problem, i got the needed operators, constructors and destructors. Can you unmarked my question ? Nobody will read if it's marked as duplicate :( – Csi Apr 28 '15 at 17:58

0 Answers0