Ошибка печати Valgrind, когда ее нет?

Я создаю шахматную программу на C. Я запустил valgrind в программе и получил:

==6683== Conditional jump or move depends on uninitialised value(s)
==6683==    at 0x405F23: getBestMove (MiniMax.c:318)
==6683==    by 0x403933: computerTurn (Chess.c:864)
==6683==    by 0x402947: runGame (Chess.c:579)
==6683==    by 0x403F66: main (Chess.c:981)



move_t* getBestMove(game_t game, int player, unsigned int depth)
{
  move_t *cur = NULL, *best = NULL;
  double alpha = INT_MIN, score = 0;
  firstMove = NULL;

  cur = getAllMoves(game, player);

  firstMove = 0;
  while (cur != NULL)
  {
    game_t copy;
    copyGame(game, &copy);
    makeMove(&copy, *cur);
    //root->game = copy;
    firstMove = NULL;
    score = -alphaBetaMax(-INT_MAX, -alpha, depth - 1, copy, !player);
    freeGame(copy);

    if (board_count > MAX_BOARDS)
      break;

    if (score > alpha) // line 318
    { 
      alpha = score;

      if (best != NULL)
      {
        best->next = NULL;

        free(best);
      }

      best = copyMove(*cur);
    }

    cur = cur->next;
  }

  freeMoves();

  if (board_count > MAX_BOARDS)
  {
    free(best);

    return 0;
  }

  return best;    
}

Чего я не понимаю, так это того, что обе переменные в if (score, alpha) инициализированы в (0, INT_MIN) соответственно. Так почему же valgrind выводит эту ошибку? Любая помощь приветствуется!

Спасибо за помощь, переход на DBL_MAX не повлиял на проблему. Вот код для alphaBetaMax:

static double alphaBetaMax(double alpha, double beta, int depthleft,
    game_t game, bool player)
{
  move_t *cur;
  double score = 0;
  bool did_move = false;

  cur = getAllMoves(game, player); // firstMove is a global list of all moves for current player
  firstMove = 0;

  while (cur != NULL)
  {
    game_t copy;
    if (depthleft <= 0 && !isCapture(game, cur))
    {
      cur = cur->next;
      continue;
    }
    did_move = true;
    copyGame(game, &copy);
    makeMove(&copy, *cur);
    firstMove = NULL;

    score = -alphaBetaMax(-beta, -alpha, depthleft - 1, copy, !player);

    if (board_count > MAX_BOARDS)
      break;

    freeGame(copy);

    if (score > alpha) // ln 278
      alpha = score;

    if (beta <= alpha) // ln 281
      break;

    cur = cur->next;
  }

  freeMoves();

  if (!did_move)
    alpha = evaluate(game) * (player * 2 - 1);

  return alpha;
}

Valgrind выводит то же сообщение относительно строк 278 и 281, и мне трудно понять, почему. Спасибо за помощь!


person John    schedule 25.09.2014    source источник
comment
stackoverflow.com/questions/2612447/   -  person pm100    schedule 25.09.2014
comment
Я использовал --track-origins = yes, и сообщения об ошибках, которые выводит valgrind, остались прежними.   -  person John    schedule 25.09.2014
comment
Вы можете разместить код производителя alphaBetaMax?   -  person DeadCalimero    schedule 25.09.2014
comment
Я ставлю на то, как game изменяется / создается / копируется и как это влияет на alpha через eumulate().   -  person alk    schedule 26.09.2014
comment
Возможно, у copyGame есть кодовый путь, который фактически не изменяет свой второй аргумент?   -  person Austin Phillips    schedule 26.09.2014
comment
Спасибо за ответы! Игра - это структура, которая содержит текущую доску и другую важную для игры информацию, такую ​​как поворот, способность к рокировке и столбец на проходе, все из которых не имеют отношения к альфа / бета.   -  person John    schedule 26.09.2014


Ответы (3)


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

E.g.:

int uninitialized;

int badStuff( bool val )
{
    if ( val ) return uninitialized;
    return 0;
}

void bestMove()
{
   int alpha = 5;
   int score = badStuff( getRandomBoolean() ); // valgrind sez: "this is a-ok."

   if ( alpha > score )   // valgrind sez: "but now you're playing with fire."
       doStuff();
}
person Rafael Baptista    schedule 25.09.2014

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

Чтобы проиллюстрировать, как возможна эта ошибка, рассмотрим фрагмент кода ниже, который предоставляет альтернативные реализации используемых функций:

void copyGame(int input, int *output) {
    /* Not initialising output as expected, causes valgrind uninitialised value
     * error.
     */
}


int alphaBetaMax(int x, int y) {
    return y + x;
}


int main(int argc, const char* argv[]) {

    int game;
    int score;

    copyGame(10, &game);
    score = alphaBetaMax(2, game);

    if (score >= 15)   /* Line 22 */
        return 0;

    return 1;
}

Результатом этого является следующий вывод valgrind:

==29812== Conditional jump or move depends on uninitialised value(s)
==29812==    at 0x400503: main (main.c:22)

Как видите, настоящая ошибка в том, что copyGame не изменяет свою переменную output, в результате game используется функцией alphaBetaMax в неинициализированном состоянии.

Если вы рассмотрите все пути кода, вы, вероятно, найдете случай, когда у вас будет такая же проблема с game неинициализированным.

person Austin Phillips    schedule 25.09.2014

Valgrind имеет параметр командной строки --track-origins=yes, который, если он установлен, сообщит вам источник неинициализированного значения. Как уже говорили другие, вероятная причина в вашем случае где-то в функции alphaBetaMax().

Если установлено значение «да», Memcheck отслеживает происхождение всех неинициализированных значений. Затем, когда сообщается об ошибке неинициализированного значения, Memcheck попытается показать происхождение значения.

...

Накладные расходы на производительность: отслеживание происхождения стоит дорого. Это вдвое снижает скорость Memcheck и увеличивает использование памяти минимум на 100 МБ, а возможно и больше. Тем не менее, он может значительно сократить усилия, необходимые для выявления основной причины ошибок неинициализированного значения, и поэтому часто помогает программисту повысить производительность, несмотря на то, что он работает медленнее.

person SoapBox    schedule 25.09.2014