在 C++ 中清除堆栈中分配的内存
Posted
技术标签:
【中文标题】在 C++ 中清除堆栈中分配的内存【英文标题】:clearing memory allocated in stack in c++ 【发布时间】:2011-08-17 06:18:59 【问题描述】:我在 C++ 中使用递归算法实现了一个国际象棋机器人,该程序每次移动评估超过一百万个节点。
随着时间的推移,它占用的内存会超过 1 GIG 的 RAM...
但我真的不需要在我完成移动后之前声明的变量...
那么如何像java的垃圾收集器一样手动刷新栈内存来清除栈上之前声明的变量呢?
更新
我发现我的源码中有这一行:
Move * M = new Move(x1,y1,x2,y2);
pair <Move *, Piece *> pr (M,aPiece);
它在执行移动函数中,该函数在递归中被调用一百万次......
我的问题是,一旦所有的递归完成并且我不再需要这个变量,你将如何清除这个变量,但是当递归正在做它的事情时,我需要那个变量留在内存中?
【问题讨论】:
你的递归方法是使用尾调用吗? en.wikipedia.org/wiki/Tail_call @dkackman 在国际象棋程序中极不可能,如果是现代 C++ 编译器会对其进行优化。 大声笑我几乎使用了 negascout 算法:en.wikipedia.org/wiki/Negascout 【参考方案1】:基于堆栈的存储在其所在的函数调用返回后立即被回收。
您是否可能在递归函数中使用了堆分配内存(即调用new
)?或者,如果您只是查看 Windows 任务管理器或等效项,您可能会看到“峰值”使用情况,或者看到您的程序释放内存和返回到操作系统内存池之间的一些延迟。
跟进(编辑问题后):
不清楚你在用pair<Move*, Piece*>
做什么,所以我不知道 Move 对象是否需要被指针持有。通过指针保存它们的主要原因是多态性(此处未使用,因为您似乎没有创建子类对象)并允许它们的生命周期独立于调用堆栈。听起来你也没有这个理由。那么,为什么不呢:
std::pair<Move, Piece*> pr(Move(x1,y1,x2,y2), aPiece);
【讨论】:
是的,我发现这个新声明可能是问题所在...(检查上面的更新描述)【参考方案2】:我假设您有一些临时变量,在递归调用返回后您不需要仍然保留这些变量。如果是这种情况,您可以在函数内自己的范围内声明它们。一旦你离开那个作用域,在其中声明的自动变量就不会再占用堆栈空间了。
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;
【讨论】:
我认为该标准允许编译器优化 POD 变量的生命周期。任何析构函数的调用时间都将是明确的,所以也许这个例子最好使用类变量。【参考方案3】:你没有 - 没有办法处理编译器实现的堆栈。您需要实现自己的堆栈,当然可以随意使用。
【讨论】:
【参考方案4】:我认为您的“堆栈”分配对象更有可能与此无关,实际上您忘记了delete
之前new
d 的东西。也许那个Move
对象?
【讨论】:
【参考方案5】:关于更新:为什么是Move*
和new Move
? Move
听起来像一个值对象,可以复制。同上Piece
(但这不太确定——你可以有独特的实例
每个Piece
)。
【讨论】:
以上是关于在 C++ 中清除堆栈中分配的内存的主要内容,如果未能解决你的问题,请参考以下文章