0

我正在尝试制作一个国际象棋程序,但我希望能够在其中实现不同的 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。

4

3 回答 3

1

你打电话selectedAI = -1;,然后AIlist[selectedAI]->...AIlist[-1]除了未定义的行为之外,您还期望是什么?

于 2013-03-11T09:19:08.833 回答
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.

于 2013-03-11T09:19:18.397 回答
0

我希望这是因为AIlist[selectedAI]超出了界限。您可以通过将其替换为 来确认这一点AIlist.at(selectedAI)。请记住,此索引在构造函数之后立即为 -1...

于 2013-03-11T09:19:39.390 回答