2013-03-11 6 views
0

Я пытаюсь создать шахматную программу, но я хочу иметь возможность реализовывать в ней различные ИИ. Таким образом, я сделал абстрактный AIgeneric класс и производный класс AIrandom от AIgeneric. Затем в моем интерфейсе chessAI я создаю список ИИ и пытаюсь вызвать их функцию getNextMove и запустить segfault. Код выглядит следующим образом:Вызов виртуального метода производного класса вызывает segfaults

class AIgeneric { 
    public: 
     virtual int getNextMove(int*, const int &) = 0; 
} 

class AIrandom : public AIgeneric { 
    public: 
     AIrandom(); 
     virtual int getNextMove(int*, const int &); 
} 


class chessAI { 
    public: 
     chessAI(); 
     ~chessAI(); 
     void setAI(); 
     int getNextMove(int*, const int &); 
    private: 
     vector<AIgeneric*> AIlist; 
     vector<string> names; 
     int selectedAI; 
}; 


chessAI::chessAI() { 
    AIrandom randomAI; 
    AIlist.push_back(&randomAI); 
    names.push_back("Random AI"); 
    selectedAI = -1; 
} 

int chessAI::getNextMove(int * board, const int & color) { 
    return AIlist[selectedAI]->getNextMove(board, color); //segfault on this line 
} 

Было бы здорово, если бы кто-нибудь мог помочь мне в решении этой проблемы!

Редактировать: Я устанавливаю selectedAI в 0 перед вызовом getNextMove.

ответ

1

В этом коде:

chessAI::chessAI() { 
    AIrandom randomAI; 
    AIlist.push_back(&randomAI); 
    names.push_back("Random AI"); 
    selectedAI = -1; 
} 

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

Помните, что все локальные переменные хранятся в стеке, а стек используется в других функциях. Поэтому, когда вы используете указатель в векторе, теперь он указывает на какую-то другую память функций, а не на тот объект, который вы объявили.

Это может быть решена тремя способами:

  1. Выделяют объект в куче:

    AIlist.push_back(new AIRandom); 
    
  2. Не используя указатели на всех.

  3. Используйте умные указатели, такие как std::unique_ptr.

+0

Да, это решило это. Благодаря! –

1

Вы звоните selectedAI = -1;, а затем AIlist[selectedAI]->.... Что вы ожидаете от AIlist[-1], кроме неопределенного поведения?

+0

К сожалению, между этим временем я все setAI() запрашивает у пользователя ввод числа, и я убедился, что selectedAI был 0 в данный момент звонка –

0

Я ожидаю, что это связано с тем, что AIlist[selectedAI] находится за пределами. Вы можете подтвердить это, заменив его на AIlist.at(selectedAI). Имейте в виду, что этот индекс равен -1 сразу после конструктора ...

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