Monte Carlo树搜索中树结构删除的内存泄漏疑问
关于Monte Carlo树搜索节点删除函数的内存泄漏问题
我在实现Monte Carlo树搜索时,用以下结构体和函数存储游戏树:
struct Node { Move move; double visits = 0; double priorProbability = 0; double QValueSum = 0; double stateValue = 0; std::vector<Node*> children; }; Node *newNode(Move move) { Node *temp = new Node; temp->move = move; return temp; }
同时写了这个prune函数用来删除节点:
void prune(Node* toPrune) { for (int i = 0; i < toPrune->children.size(); ++i) { prune(toPrune->children[i]); } toPrune->children.clear(); delete toPrune; }
不确定这个函数会不会引发内存泄漏,想确认实现是否安全。
这个prune函数的实现不会导致内存泄漏,原因如下:
- 采用递归遍历逻辑,先递归删除当前节点的所有子节点及其后代,确保所有动态分配的节点都被处理,没有遗漏
- 清空
children向量的操作不是必须的——因为节点销毁时,std::vector会自动析构并释放自身内存,但这个操作也不会带来负面影响 - 所有通过
newNode用new分配的节点,最终都会被delete释放,不存在未被回收的动态内存
不过有几个需要注意的细节:
- 调用
prune的节点必须是通过new分配的(也就是newNode返回的节点),如果传入栈上的节点,会触发未定义行为 - 如果程序其他地方还有指向这些节点的指针,调用
prune后这些指针会变成悬空指针,后续使用会导致程序崩溃或异常 - 更稳妥的方式是用智能指针(比如
std::unique_ptr<Node>)管理节点内存,这样不需要手动编写prune函数,能彻底避免手动管理内存的风险
内容的提问来源于stack exchange,提问作者daan
相关产品推荐
相关产品推荐

