【发布时间】:2015-12-17 16:33:51
【问题描述】:
我正在开发一个下棋程序。作为其中的一部分,我编写了一个静态方法,该方法应该通过使用各种版本的板子(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];
};
我们的目标是最终让递归方法的初始调用结果包含一个“最佳”值,该值通过棋盘链接到整个最佳路径选择链。然后我会画出产生的一系列棋盘状态。
作为其中的一部分,必须保留电路板。在每个递归步骤中,无论哪个棋盘“获胜”都会被复制到动态内存中,并且返回的棋盘指针( Piece * (*board)[8] 在 node 声明中) 设置为此动态分配的内存。
这样做是这样的:
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 的所有值复制到全局板上,返回并将该全局板直接绘制到屏幕上,它会绘制正确的结果。同样,如果我将 ret->board 设置为指向该全局板,然后将值复制到全局板并返回,它会绘制正确的值。
但是,如果我按照上面写的操作并尝试绘制 ret->board,我的绘制方法中会出现无效的内存访问错误,我正在努力尝试来解决这个问题。似乎在返回后立即以某种方式回收了 reboard 指向的内存。在这个应该只是数据的内存中,我看到数组中的条目似乎指向 msctf.dll 中的代码,以及其他无效的数据指针。我认为它正在被垃圾收集回收,所以我什至尝试对我能看到的任何指针进行一些 std::declare_reachable 调用,但这没有帮助。
有人注意到这里发生了什么吗?在我释放它之前,动态分配的内存不应该一直存在吗?
【问题讨论】:
-
查看位板;它们比您的数据结构更好。此外,国际象棋引擎代码中的堆应该很少。我只在转置表和线程设置期间使用堆分配。上下游戏树不需要堆分配——所有东西都应该预先分配。
标签: c++ memory memory-management recursion garbage-collection