0

チェスプログラムを作ろうとしていますが、さまざまなAIを実装できるようにしたいと思っています。したがって、私はAIgenericから抽象AIgenericクラスと派生クラスAIrandomを作成しました。次に、chessAIインターフェイスで、AIのリストを作成し、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つのオブジェクトではなく、他の関数メモリを指すようになります。

これは、次の3つの方法で解決できます。

  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 に答える