3

I'm programming a chess engine in C and ran it through Valgrind and got this:

==20217== 672 (32 direct, 640 indirect) bytes in 1 blocks are definitely lost in loss record 39 of  98
==20217==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20217==    by 0x40143A: register_move (Chess.c:236)
==20217==    by 0x4015B6: scan_in_direction (Chess.c:256)
==20217==    by 0x402131: getBishopMoves (Chess.c:374)
==20217==    by 0x401296: getSquareMoves (Chess.c:190)
==20217==    by 0x400C94: getAllMoves (Chess.c:60)
==20217==    by 0x405C19: alphaBetaMax (MiniMax.c:260)
==20217==    by 0x405D02: alphaBetaMax (MiniMax.c:274)
==20217==    by 0x405D02: alphaBetaMax (MiniMax.c:274)
==20217==    by 0x405D02: alphaBetaMax (MiniMax.c:274)
==20217==    by 0x405ECD: getBestMove (MiniMax.c:307)
==20217==    by 0x403933: computerTurn (Chess.c:850)

The function register_move is:

static void register_move(game_t game, int x1, int y1, int x2, int y2, char special,
          int color) {
    move_t *tmpMove = (move_t *)malloc(sizeof(move_t));
    checkMalloc(tmpMove);
    tmpMove->x1 = x1;
    tmpMove->y1 = y1;
    tmpMove->x2 = x2;
    tmpMove->y2 = y2;
    tmpMove->s = special;
    firstMove = addToList(game, firstMove, tmpMove, color); //firstMove is a global list of moves
}

EDIT: for further clarity, move_t is defined as:

struct move_t {
    int x1;
    int y1;
    int x2;
    int y2;
    char s;
    struct move_t *next;
};

typedef struct move_t move_t;

MORE EDITS: firstMove is a global list of moves. The function addToList as referenced above is:

move_t *addToList(game_t game, move_t *list, move_t *move, int color) {
    int kx, ky;
    game_t copy;
    copyGame(game, &copy);
    makeMove(&copy, *move);

    kx = copy.data[2];
    ky = copy.data[3];
    if (color) {
        kx = copy.data[0];
        ky = copy.data[1];
    }
    if (isAttacked(&copy, kx, ky, color) == 0) {
        move->next = list;
        list = move;
    } else {
        free(move);
    }
    freeGame(copy);
    return list;
}

If the potential move is illegal, i.e. the curplayer's king is in check, the move is not added to the list and instead freed. It could be possible that the problem is in the freeing of firstMove, which happens throughout the program.

Why does Valgrind think there seems to be an issue with the malloc? It seems alright to me. How do I interpret this?

dhag
  • 139
  • 1
  • 5
  • 10
John
  • 53
  • 3
  • 4
    The node you just allocated and *presumably* linked to your `firstMove` headed linked list is never freed. None of the code that would do that is present here, nor the logic in calling it (if it is done at all). In simpler terms: your linked list node management code has at least one bug. Were I to *guess* (which is all I can do as nearly all of your list code is *not* presented), since there is only one node doing this, it is likely the head or tail node you're neglecting.([And stop casting `malloc` in C programs](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)). – WhozCraig Sep 29 '14 at 13:08
  • Alright, I removed the follow-up and added more details to the question. – John Sep 29 '14 at 13:16
  • 2
    Valgrind shows where you allocated memory. The only question you should ask yourself in that situation is *where it should be freed*. If you don't know the answer, valgrind isn't to blame. If you do, double-check that this specific allocated block is being freed *there* (because it isn't). – keltar Sep 29 '14 at 15:03
  • I guess you just do `free(firstMove)` in your code which causes you to lose the pointer to all following list elements. You have to free each element separately (e.g. using a loop). – Roland W Sep 29 '14 at 15:14
  • Thanks for the help, I'll check the freeing of firstMove more thoroughly. – John Sep 29 '14 at 15:34
  • And make certain the starting address for `move` hasn't changed before you call `free(move);`. – David C. Rankin Mar 23 '15 at 23:33

0 Answers0