Author: Marcus Heidkamp
Date: 04:48:28 06/05/01
I felt a little uncomfortable in getting those memory leaks while using
Nalimov's TB indexing code (I know that the OS will clean up those at program
exit, it's just a habit not no leave allocated memory flying around...). So here
is my solution to clear up the memory once the program stops:
void IFreeReference(CUTbReference* putbr, int nDepth)
{
int i;
if (nDepth > 0)
for (i = 0; i <= putbr[0].m_cPieces; i++)
IFreeReference(putbr[i + 1].m_utbReference, nDepth - 1);
if (nDepth != 9)
free(putbr);
}
extern "C" void ICloseTb(void)
{
VTbCloseFiles();
piece pi1;
piece pi2;
#if defined (T41_INCLUDE)
piece pi3;
#endif
if (fEnumerationInitted)
{
fEnumerationInitted = false;
// free square tables
for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
free(rgprgsqPiece[pi1]);
for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1))
{
// free enumeration tables for single piece
free(rgprgulSinglePawnPresent[pi1]);
if (pi1 > x_piecePawn)
free(rgprgulSinglePawnless[pi1]);
// free enumeration tables for pair of pieces
for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 =
(piece) (pi2 + 1))
{
free(rgprgulPairPawnPresent[pi1][pi2]);
if (pi1 > x_piecePawn && pi2 > x_piecePawn)
free(rgprgulPairPawnless[pi1][pi2]);
#if defined (T41_INCLUDE)
// free enumeration tables for three pieces
for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3
= (piece) (pi3 + 1))
{
if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn)
free(rgprgulTriplePawnPresent[pi1][pi2][pi3]);
else
free(rgprgulTriplePawnless[pi1][pi2][pi3]);
}
#endif
}
}
}
int i, iTb, sd;
for (iTb = 1; iTb < cTb; iTb ++)
{
for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1))
{
if (NULL != rgtbdDesc[iTb].m_rgpbRead[sd])
{
free(rgtbdDesc[iTb].m_rgpbRead[sd]);
rgtbdDesc[iTb].m_rgpbRead[sd] = NULL;
}
if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd])
{
free (rgtbdDesc[iTb].m_prgtbcbBuckets[sd]);
rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL;
}
if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd])
{
free (rgtbdDesc[iTb].m_rgpchFileName[sd]);
rgtbdDesc[iTb].m_rgpchFileName[sd] = NULL;
}
if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd])
{
free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd]);
rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd] = NULL;
}
}
}
// Free compressed blocks
for (i = 0; i < CPUS; i ++)
{
if (NULL != rgpdbDecodeBlocks[i])
{
free (rgpdbDecodeBlocks[i]);
rgpdbDecodeBlocks[i] = NULL;
}
}
// free the search tree
if (fTbTableCreated)
{
fTbTableCreated = false;
IFreeReference(rgutbReference, 9);
}
}
I did not bother with the code for mapping whole files to memory, because I do
not use these features yet. Likely, that the buffers have be freed as well...
Marcus
This page took 0.01 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.