2015-07-27 2 views
0

Я программирую настольную игру. Когда я вызываю конструктор (с параметрами) для игры, программа segfaults.Вызов класса конструктора вызывает segfault (C++)

Главный файл:

#include <iostream> 
#include "game.h" 
using namespace std; 

int main(){ 
    int p_count = 2; 
    Game g(p_count); 
    //g.play(); 
} 

игры Заголовок:

#ifndef GAME_H_ 
#define GAME_H_ 
#include <iostream> 
#include "board.h" 
#include "player.h" 

using namespace std; 

class Game{ 

private: 
    Board    b; 
    int     moves, gamers; 
    Player    players[10]; 
    bool    running; 

public: 
    Game      (int p_count); 
    void setup    (); 
    void play    (); 
    void report_score  (); 
    bool in_mate    (Player p); 
    bool in_check   (Player p); 
}; 

игры Constructor:

#include "game.h" 

Game::Game(int p_count){ 
    running = true; 
    moves = 0; 
    gamers = p_count; 
    } 

заголовка Board

#ifndef BOARD_H_ 
#define BOARD_H_ 
#include <iostream> 

using namespace std; 

class Piece; 

class Board{ 

private: 
    static const int SIZE = 8; 
    Piece *board[SIZE][SIZE]; 

public: 
    Board    (); 

}; 


#endif /* BOARD_H_ */ 

Board конструктор

#include "board.h" 
#include "piece.h" 
Board::Board(){ 
    bool b = false; 
    for (int i=0; i<SIZE; i++){ 
     for(int j=0; j<SIZE;j++){ 
      board[i][j]->set_status(b); 
     } 
    } 
} 

Заголовок игрока

#ifndef PLAYER_H_ 
#define PLAYER_H_ 
#include <iostream> 
#include "board.h" 
#include "piece.h" 

using namespace std; 

class Player{ 

private: 
    static const int NUM = 16; 
    Piece pieces[NUM]; 
    int side; 
public: 
    Player    (); 
    Player    (int p); 
#endif 

конструктор игрока

#include "player.h" 
Player::Player(){ 
    side = 0; 
} 

Заголовок Кусок

#ifndef PIECE_H_ 
#define PIECE_H_ 
#include <iostream> 
#include "board.h" 

using namespace std; 

class Board; 

struct location{ 
    int row; 
    int col; 
}; 

class Piece{ 

private: 
    location pos_moves[50], loc; 
    char  type; 
    bool  status; 
    int   moved, team; 

public: 
    Piece     (); 
    Piece     (int piece_num, int bel); 
    void set_status  (bool b); 
}; 

#endif /* PIECE_H_ */ 

реализация Кусок

#include "piece.h" 
Piece::Piece(){ 
    status = false; 
    team = 0; 
    moved = 0; 
    type = 'A'; 
} 

void Piece::set_status(bool b){ 
    status = b; 
} 

Я называю некоторые функции из конструктора, который инициализирует неиспользуемые переменные, но сбой программы, независимо от того, или нет они включены.

+3

Что делают конструкторы 'Player' и' Board'? – StenSoft

+0

Игрок, о котором я упоминал, вызывается в конструкторе, который вызывает доску, и между ними многое сделать, чтобы настроить игру. Но, как я сказал, комментирование их из конструктора по-прежнему вызывает его segfault, поэтому я решил, что они не являются источником проблемы. – Jordan

+0

Их конструкторы называются неявно, даже если вы прокомментируете явную инициализацию. Также обратите внимание, что если вы инициализируете их с помощью 'b = Board (...)' в теле конструктора, он до сих пор будет вызывать конструкторы по умолчанию. Вместо этого вы должны использовать [список инициализаторов] (http://en.cppreference.com/w/cpp/language/initializer_list). – StenSoft

ответ

0

board является 2-d массив указателя Piece, вы должны new его перед использованием его в Board «s CTOR:

Board::Board(){ 
    bool b = false; 
    for (int i=0; i<SIZE; i++){ 
     for(int j=0; j<SIZE;j++){ 
      board[i][j] = new Piece; // add it here 
      board[i][j]->set_status(b); 
     } 
    } 
} 

BTW, не забудьте delete указатели, может быть, в Board 's dtor.

+0

Это было сделано. Спасибо за помощь. – Jordan

3

Одна проблема, которую я вижу, что вы определили board как массив указателей, а не объекты,

Piece *board[SIZE][SIZE]; 

а затем продолжить использовать board в Game::Game() как будто board указывает на действительные объекты.

Board::Board(){ 
    bool b = false; 
    for (int i=0; i<SIZE; i++){ 
     for(int j=0; j<SIZE;j++){ 

     // Problem. 
     // board[i][j] has not been initialized 
     // to point to any valid object. 
     board[i][j]->set_status(b); 
     } 
    } 
} 

Вы можете решить, что, делая board массивом объектов.

Piece board[SIZE][SIZE]; 

или убедитесь, что вы выделили память каждого элемента массива перед их использованием.

Board::Board(){ 
    bool b = false; 
    for (int i=0; i<SIZE; i++){ 
     for(int j=0; j<SIZE;j++){ 

     // Allocate memory for the element 
     // of the array. 
     board[i][j] = new Piece; 
     board[i][j]->set_status(b); 
     } 
    } 
} 

Я рекомендую использовать массив объектов. Тогда вам не придется беспокоиться о распределении памяти и освобождении. Если вы используете массив указателей, прочитайте The Rule of Three.

+0

Также я не вижу функцию set_status (bool) члена Piece в ее объявлении. –

+0

Это по существу, где возникла проблема. Сначала у меня было все как объекты без указателей. Он работал некоторое время, но, как я разработал больше кода, я понял, что мне нужны форвардные декларации для «доски» и «кусок» (я относительно новичок в программировании). Когда я добавил, что на доске и кусках заголовков, ошибка компилятора сказала мне, что плата Piece [SIZE] [SIZE] имеет «неполный тип». Решением было объявить его как указатель. Как вы сказали, что он не идеален для использования указателей, но я не знаю другого решения. Спасибо за вашу помощь. – Jordan

+0

@ Jordan, вы можете использовать любой из этих подходов, чтобы заставить вашу программу работать. Понимать плюсы и минусы каждого подхода. Вы даже можете реализовать его в обоих направлениях, чтобы увидеть, какой из них вам больше нравится :) –

Смежные вопросы