Почему я теряю память здесь (поиск в глубину) c ++? - PullRequest
0 голосов
/ 09 марта 2012
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 ]

2 голосов
/ 09 марта 2012

У вас есть 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 голос
/ 09 марта 2012
Контейнер

A 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], который мы выделили и поместили в вектор.

0 голосов
/ 09 марта 2012

Мне кажется, что вы никогда не очищаете «минимальные» позиции.

Вы сохраняете указатель на доску в best, и позаботьтесь о том, чтобы очистить его, если вы замените его на лучший минимум, а в случае, если движение пока не является минимальным, вы правильно очистите его, но Вы никогда не очищаете указатель фактической позиции, если он минимальный.

Как примечание стороны, это избыточно:

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