我正在制作一个国际象棋游戏计划。作为其中的一部分,我编写了一个静态方法,应该通过调用自身的各种版本的板, Piece * board [8] [8] 来递归操作其输入,然后传回来" best"的位置 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];
};
目标是最终对递归方法的初始调用的结果包含一个&#34; best&#34;通过棋盘链接到整个最佳路径选择链的值。然后我会画出一系列导致的董事会状态。
作为其中的一部分,必须保留董事会。无论哪个董事会赢得胜利#34;在每个递归步骤中复制到动态内存,返回的板指针(节点声明中的 Piece *(* board)[8] )设置为动态分配内存。
这样做是这样的:
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-&gt; board 设置为指向该全局板,然后将值复制到全局板并返回,则会绘制正确的值。
但是,如果我按照上面所写的方式进行操作并尝试绘制 ret-&gt; board ,我的绘制方法会出现无效的内存访问错误,而且我是拉我的头发试图把这个问题解决。似乎在返回之后, reboard 指向的内存以某种方式被回收。在这个应该只是数据的内存中,我看到数组中的条目似乎指向msctf.dll中的代码,以及其他无效数据指针。我认为垃圾收集正在回收,所以我甚至尝试在我能看到的任何指针上加入一些 std :: declare_reachable 调用,但这没有帮助。
任何人都会注意到这里发生了什么?不应该动态分配内存,直到我释放它?
答案 0 :(得分:0)
std :: unique_ptr是一个智能指针,它通过指针保留对象的唯一所有权,并在unique_ptr超出范围时销毁该对象。没有两个unique_ptr实例可以管理同一个对象。
换句话说,只要点击return
,就会释放内存,然后返回垃圾。当然,它会导致访问冲突,试图取消引用该内存。