为什么我在这里泄漏内存(深度优先搜索)c ++?

时间:2012-03-08 20:12:12

标签: c++ memory pointers memory-leaks depth-first-search

int Solver::negamax(Position* pos,int alpha,int beta, int color, int depth ) {
  if(depth==0 || is_final(pos)){
    return evaluate(pos);
  }
  else{
    vector < Position* > moves = generate_moves(pos->get_board());
    vector < Position* >::iterator move;
    int min = 99999;
    for(move = moves.begin(); move < moves.end(); move++){
      int val = negamax(*move,alpha, beta, -color, depth - 1 );
      if(val <= min){
        min = val;
        delete best;
        best = NULL;
        best = (*move)->get_board();

      }
      else{
        delete *move; //So this isnt cleaning up?
        *move = NULL;
      }
     }
     min = -min;
     return min;
     }

 }

vector < Position* > TakeAwaySolver::generate_moves(Board *brd){
  TakeAwayBoard *board = static_cast<TakeAwayBoard*>(brd);
  vector < Position* > moves;
  if(board->get_data() >= 3){
     TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 3);
     Position* p = new Position(b);
     moves.push_back(p);
  }
  if(board->get_data() >= 2){
     TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 2);
     Position* p = new Position(b);
     moves.push_back(p);
  }
  TakeAwayBoard *b = new TakeAwayBoard(board->get_data() - 1);
  Position* p = new Position(b);
  moves.push_back(p);
  return moves;

}

我认可了我的计划,而且我显然是在泄漏记忆。似乎我正在删除所有未使用的对象,但也许我不理解某些东西。 generate_moves()确实为每个被推入的对象分配内存。评估返回1.我是否可能在任何位置泄漏内存?

3 个答案:

答案 0 :(得分:2)

您有一个if / else,其中* move仅在其中一个路径中删除。我在那里检查。

for(move = moves.begin(); move < moves.end(); move++){
          int val = negamax(*move,alpha, beta, -color, depth - 1 );
          if(val <= min){
            min = val;
            delete best;
            best = NULL;
            best = (*move)->get_board();
                                           //best is deleted, but *move is not
          }
          else{
            delete *move;
            *move = NULL;
          }
         }

答案 1 :(得分:1)

std::vector<position *>容器在销毁时不会自动删除插入的元素。设为std::vector<x<position *> >,其中x是一些合适的智能指针模板,如auto_ptr

如果你不想这样做,那么下一个最好的事情是将向量包装在一个类中,该析构函数遍历向量并在每个指针上调用delete。

即。这是内存泄漏:

{
   std::vector<int *> vec;
   vec.push_back(new int[3]);
   // vec goes out of scope
}

当然,矢量会自行清理!它删除了它的内部数组等。但它对我们分配并放入向量的new int[3]没有任何作用。

答案 2 :(得分:0)

在我看来,你永远不会清除'最低'的位置。

您可以在best中存储指向电路板的指针,并在更换最小电路时将其清除,如果移动距离不是最小,则可以正确清理它,但是如果它是最小值,你永远不会清理实际的位置指针。

作为旁注,这是多余的:

    best = NULL;
    best = (*move)->get_board();