我使用递归算法在c ++中实现了一个国际象棋机器人,该程序每次移动评估超过一百万个节点。
随着时间的推移,它占用的内存超过1 GIG的RAM ......
但我真的不需要在完成移动后先前声明的变量......
那么如何手动刷新堆栈内存以摆脱堆栈中先前声明的变量,就像java的垃圾收集器一样?
我发现我的来源中有这一行:
Move * M = new Move(x1,y1,x2,y2);
pair <Move *, Piece *> pr (M,aPiece);
并且它在执行移动函数中,在递归中被称为一百万次......
我的问题是,一旦完成所有递归并且我不再需要这个变量,你将如何清除这样的变量,但是当递归正在做它的事情时,我需要该变量留在内存中?
答案 0 :(得分:8)
基于堆栈的存储在其驻留的函数调用返回后立即回收。
您是否有可能在递归函数中使用堆分配的内存(即调用new
)?或者,如果您只是查看Windows任务管理器或等效项,您可能会看到“峰值”使用情况,或者看到程序释放的内存与返回到操作系统内存池之间存在一些延迟。
跟进(问题编辑后):
目前还不清楚你在使用pair<Move*, Piece*>
做什么,所以我无法判断Move对象是否需要由指针保持。通过指针保存它们的主要原因是多态(这里没有使用,因为你似乎没有创建子类对象)并允许它们的生命周期独立于调用堆栈。听起来你也没有这个理由。那么,为什么不呢:
std::pair<Move, Piece*> pr(Move(x1,y1,x2,y2), aPiece);
答案 1 :(得分:1)
我假设你有一些临时变量,在递归调用返回后你不需要仍然存在。如果是这种情况,您可以在函数内的自己的范围内声明它们。离开该范围后,在其中声明的自动变量将不再占用堆栈中的空间。
int recursive_function(int a, int b){
int total;
{ //new scope
int temp[20];
//do stuff using temp and total
} //temp goes out of scope, not taking up space on stack anymore
total += recursive_function(a+total,b);
{
int temp[25];
//do stuff with this other temp
}
total += recursive_function(a,b+total);
return total;
}
编辑:
为了响应您的更新,如果您使用new
分配内存,则需要在完成后将其与delete
一起释放。在这种情况下,该行将是delete M;
void recursive_function(pair <Move *, Piece *> last_move){
Move * M = new Move(x1,y1,x2,y2);
pair <Move *, Piece *> pr (M,aPiece);
recursive_function(pr);
delete M;
}
答案 2 :(得分:0)
你没有 - 没有办法处理编译器实现的堆栈。你需要实现自己的堆栈,你当然可以这样做。
答案 3 :(得分:0)
我认为你的“堆叠”分配的对象更有可能与此无关,事实上你忘记了delete
之前new
d的东西。也许是Move
对象?
答案 4 :(得分:0)
关于更新:为什么Move*
和new Move
? Move
听起来像一个值对象,可以复制。同上Piece
(但这不太确定 - 你可以拥有独特的实例
每个Piece
)。