我正在製作一個象棋遊戲程序。作爲它的一部分,我寫了一個靜態方法,該方法應該通過調用自己的各種版本的電路板,一個Piece * board [8] [8],遞歸地操作其輸入,並傳回位置在std :: unique_ptr內的板的「最佳」版本,這是該方法的返回類型。返回後無法保持動態分配的內存一致
節點被定義爲這樣:
class node
{
public:
node();
~node();
std::unique_ptr<node> l;
std::unique_ptr<node> r;
std::unique_ptr<node> m;
node * best;
int bestval;
Piece * (*board)[8];
};
的目標是最終要遞歸方法的初始調用的結果包含一個「最佳」值,其通過鏈接到的最佳路徑選擇整個鏈棋盤。然後我會畫出一系列結果的棋盤狀態。
作爲其中的一部分,董事會必須保留。無論在每個遞歸步驟中「獲勝」的板卡都被複制到動態存儲器中,並且返回的板指針(件*(*板)[012]在節點聲明中)被設置爲該動態分配的存儲器。
這是像這樣做:那麼
std::unique_ptr<node> ret (new node);
Piece *** reboard = new Piece**[8];
for (int i = 0; i < 8; i++)
{
reboard[i] = new Piece*[8];
}
...code to copy values to reboard and set other ret property values...
ret->board = reboard;
return ret;
所有獲獎的國際象棋棋盤的本地值複製到reboard。這一切工作正常。如果我在此階段將所有reboard的值複製到全局板上,則返回並直接將該全局板繪製到屏幕上,這會得出正確的結果。同樣,如果我將ret-> board指向該全局板,然後將值複製到全局板並返回,則會繪製正確的值。
但是,如果我做什麼我寫上面,並試圖畫ret->板,我得到無效的內存訪問錯誤,在我的畫法,我拉我的頭髮試着對這個問題下。看起來在返回之後,指向的內存被以某種方式回收。在這個應該只是數據的內存中,我看到數組中的條目似乎指向msctf.dll中的代碼以及其他無效的數據指針。我認爲它被垃圾回收回收,所以我甚至試圖在我看到的任何指針上放入一些std :: declare_reachable調用,但這並沒有幫助。
任何人都可以注意到這裏發生了什麼?不應該動態分配記憶棒,直到我釋放它爲止?
看看比特板;他們比你的數據結構更好。而且,在國際象棋引擎代碼中應該只有很少的堆。我只對轉置表和線程安裝期間使用堆分配。上下游戲樹不需要堆分配 - 所有事情都應該預先分配。 – VoidStar