Computer Chess Club Archives


Search

Terms

Messages

Subject: Getting rid of memory leaks using Nalimov's code

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.