Я не понимаю, почему эта функция пропускает память. Предполагается обнаружить мат в шахматной зоне отдыха. Он использует legal_moves()
, который назначает указатель на начало списка допустимых ходов (save
здесь) и king_under_check()
, который возвращает логическое значение. Когда я запускаю его через valgrind
, у меня возникает определенная утечка памяти. Неправильно ли я предположить, что на выходе valgrind
эта функция является источником утечки?
Моя функция:
Bool is_checkmate(PlayerColor c) {
Move *list = (Move *)(calloc(1, sizeof(Move)));
Move *save = list;
unsigned int num = 0;
if(is_king_under_check(c) && !legal_moves(&save, c, &num)){
freeList(save);
return TRUE;
}
freeList(save);
return FALSE;
}
, и я использую freeList()
для освобождения списка, записанного в в legal_moves()
:
void freeList(Move *head){
Move *temp;
while(head != NULL){
temp = head;
head = head->next_move;
free(temp);
}
Here is the `valgrind` output:
==447557== 111,504 bytes in 4,646 blocks are definitely lost in loss record 44 of 47
==447557== at 0x4837B65: calloc (vg_replace_malloc.c:752)
==447557== by 0x116E55: is_checkmate (moves.c:1430)
==447557== by 0x1172BF: run_mate1 (moves.c:1486)
==447557== by 0x117CBD: run_mate2 (moves.c:1599)
==447557== by 0x109C37: main (main.c:181)
Вот моя (довольно длинная) легальная функция ходов, которая может сузить проблему:
Bool legal_moves(Move **m, PlayerColor c, unsigned int *pcount) {
/* Your implementation */
Board tempBoard = CurrentBoard;
uint64_t sq;
Move *save = (Move *)(calloc(1, sizeof(Move)));
Move *link = save;
*m = save;
Move possibleMove;
/*Move *mNode = (Move *)(calloc(1, sizeof(Move)));*/
unsigned int i, shift;
for(shift = 0; shift < 64; shift++){
/*printf("move count%d\n",*pcount);*/
sq = 1;
sq = sq<<shift;
if(player[c].k & sq){
possibleMove.from = shift;
possibleMove.piece = KING;
Pos *k_moves = king_move(possibleMove, c);
unsigned int size = *(k_moves);
unsigned int *arrPtr = k_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].k, KING, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].k, KING, c);
if(is_king_under_check(c) == TRUE){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}
else if((board_to_pos(player[BLACK].k) == NORTH_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == EAST_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == SOUTH_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == EAST_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == SW_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == SE_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == NE_OF(board_to_pos(player[WHITE].k))) ||
(board_to_pos(player[BLACK].k) == NW_OF(board_to_pos(player[WHITE].k)))){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}
else if(detect_castle_move(possibleMove, c) == 1){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
if(is_castling_valid(c) == TRUE){
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = KING;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/*free(mNode);*/
}
}
else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = KING;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/*free(mNode);*/
}
}
free(k_moves);
}
}
if(player[c].b & sq){
possibleMove.from = shift;
possibleMove.piece = BISHOP;
Pos *b_moves = bishop_move(possibleMove, c);
unsigned int size = *(b_moves);
unsigned int *arrPtr = b_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].b, BISHOP, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].b, BISHOP, c);
if(is_king_under_check(c) == TRUE){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = BISHOP;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/* free(mNode);*/
}
}
free(b_moves);
}
}
if(player[c].p & sq){
possibleMove.from = shift;
possibleMove.piece = PAWN;
Pos *p_moves = pawn_move(possibleMove, c);
unsigned int size = *(p_moves);
unsigned int *arrPtr = p_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
possibleMove.promotion_choice = UNKNOWN;
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].p, PAWN, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
if(RANK_OF(possibleMove.to) == '1' || RANK_OF(possibleMove.to) == '8'){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
int j = 0;
for(j = 0; j < 4; j++){
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->promotion_choice = UNKNOWN;
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = PAWN;
mNode->next_move = NULL;
if(j == 0) mNode->promotion_choice = QUEEN;
if(j == 1) mNode->promotion_choice = ROOK;
if(j == 2) mNode->promotion_choice = BISHOP;
if(j == 3) mNode->promotion_choice = NIGHT;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/*free(mNode);*/
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].p, PAWN, c);
if(is_king_under_check(c) == TRUE){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}
else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = PAWN;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/* free(mNode);*/
}
}
free(p_moves);
}
}
if(player[c].r & sq){
possibleMove.from = shift;
possibleMove.piece = ROOK;
Pos *r_moves = rook_move(possibleMove, c);
unsigned int size = *(r_moves);
unsigned int *arrPtr = r_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].r, ROOK, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].r, ROOK, c);
if(is_king_under_check(c) == TRUE){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = ROOK;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
}
}
free(r_moves);
}
}
if(player[c].n & sq){
possibleMove.from = shift;
possibleMove.piece = NIGHT;
Pos *n_moves = knight_move(possibleMove, c);
unsigned int size = *(n_moves);
unsigned int *arrPtr = n_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].n, NIGHT, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].n, NIGHT, c);
if(is_king_under_check(c) == TRUE){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = NIGHT;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/*free(mNode);*/
}
}
free(n_moves);
}
}
if(player[c].q & sq){
possibleMove.from = shift;
possibleMove.piece = QUEEN;
Pos *q_moves = queen_move(possibleMove, c);
unsigned int size = *(q_moves);
unsigned int *arrPtr = q_moves;
if(size > 0){
for(i = 1; i < size+1; i++){
possibleMove.to = *(arrPtr + i);
PlayerState temp = player[c];
PlayerState temp2 = player[1-c];
if(is_king_under_check(c)){
make_move(possibleMove, player[c].q, QUEEN, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
continue;
}
}
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
make_move(possibleMove, player[c].q, QUEEN, c);
if(is_king_under_check(c)){
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
}else{
Move *mNode = (Move *)(calloc(1, sizeof(Move)));
mNode->from = shift;
mNode->to = *(arrPtr + i);
mNode->piece = QUEEN;
mNode->promotion_choice = UNKNOWN;
mNode->next_move = NULL;
player[c] = temp;
player[1-c] = temp2;
CurrentBoard = tempBoard;
link = save;
while(link->next_move != NULL){
link = link->next_move;
}
link->next_move = mNode;
(*pcount)++;
/*free(mNode);*/
}
}
free(q_moves);
}
}
}
if(*pcount > 0){
return TRUE;
}else{
return FALSE;
}
}
И связанный вывод valgrind
:
==447557== 535,008 (12,792 direct, 522,216 indirect) bytes in 533 blocks
are definitely lost in loss record 47 of 47
==447557== at 0x4837B65: calloc (vg_replace_malloc.c:752)
==447557== by 0x10CA10: legal_moves (moves.c:24)
==447557== by 0x117059: run_mate1 (moves.c:1464)
==447557== by 0x117CBD: run_mate2 (moves.c:1599)
==447557== by 0x109C37: main (main.c:181)