2013-03-11 53 views
0

我試圖讓國際象棋程序,但我希望能夠在它來實現不同的認可。因此,我製作了一個抽象的AIgeneric類和AIgeneric的派生類AIrandom。然後在我的chessAI界面,我創建的認可名單,並試圖調用他們的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。

回答

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

是的,這解決了它。謝謝! – 2013-03-11 09:27:57

1

你叫selectedAI = -1;然後AIlist[selectedAI]->...。除了未定義的行爲,你期望AIlist[-1]是什麼?

+0

對不起,在那段時間之間我做了所有setAI(),它提示用戶輸入一個數字,並且我確保當前被選中的AI爲0是叫 – 2013-03-11 09:22:25

0

我想這是因爲AIlist[selectedAI]是超出界限。您可以通過將其替換爲AIlist.at(selectedAI)來確認。請記住,這個索引在構造函數之後立即爲-1 ...