我试图制作国际象棋程序,但我希望能够在其中实现不同的AI。因此,我创建了一个抽象的AIgeneric类和AIgeneric的派生类AIrandom。然后在我的chessAI接口中,我创建了一个AI列表,并尝试调用它们的getNextMove函数并进入段错误。代码如下:
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
}
如果有人能帮我解决这个问题,那就太好了!
编辑:我在调用getNextMove之前将selectedAI设置为0.
答案 0 :(得分:1)
您拨打selectedAI = -1;
然后AIlist[selectedAI]->...
。除了未定义的行为之外,您期望AIlist[-1]
是什么?
答案 1 :(得分:1)
在此代码中:
chessAI::chessAI () {
AIrandom randomAI;
AIlist.push_back(&randomAI);
names.push_back("Random AI");
selectedAI = -1;
}
将指向局部变量的指针存储到向量中。构造函数返回后,指针不再有效。
请记住,所有局部变量都存储在堆栈中,堆栈在其他函数中重用。因此,当您在向量中使用指针时,它现在指向其他一些函数内存而不是您声明的一个对象。
这可以通过三种方式解决:
在堆上分配对象:
AIlist.push_back(new AIRandom);
根本不使用指针。
使用智能指针,例如std::unique_ptr
。
答案 2 :(得分:0)
我希望这是因为AIlist[selectedAI]
超出范围。您可以将其替换为AIlist.at(selectedAI)
来确认。请记住,此索引在构造函数之后立即为-1 ...