调用派生类的虚方法会导致段错误

时间:2013-03-11 09:17:23

标签: c++ pointers derived-class

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

3 个答案:

答案 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;
}

将指向局部变量的指针存储到向量中。构造函数返回后,指针不再有效。

请记住,所有局部变量都存储在堆栈中,堆栈在其他函数中重用。因此,当您在向量中使用指针时,它现在指向其他一些函数内存而不是您声明的一个对象。

这可以通过三种方式解决:

  1. 在堆上分配对象:

    AIlist.push_back(new AIRandom);
    
  2. 根本不使用指针。

  3. 使用智能指针,例如std::unique_ptr

答案 2 :(得分:0)

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