Important Notice
The pages on this site contain documentation for very old MS-DOS software,
purely for historical purposes.
If you're looking for up-to-date documentation, particularly for programming,
you should not rely on the information found here, as it will be woefully
out of date.
HEAPWALK.C
◄Up► ◄Contents► ◄Index► ◄Back►
────────────────────────────────────────────────────────────────────────────
/* HEAPWALK.C illustrates heap testing functions including:
* _heapchk _heapset _heapwalk _msize
*/
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
/* Macro to get a random integer within a specified range */
#define getrandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
int _far *heapvalidate( char fill ); /* Prototypes */
void heapstat( int status );
void main()
{
unsigned *p[10];
int i, _far *perr;
srand( (unsigned)time( NULL ) ); /* Seed with current time */
/* Check heap status. Should be OK at start of heap. */
heapstat( _heapchk() );
/* Now do some operations that affect the heap. In this example,
* allocate random-size blocks.
*/
for( i = 0; i < 10; i++ )
{
if( (p[i] = (unsigned *)calloc( getrandom( 1, 10000 ),
sizeof( unsigned ) )) == NULL )
{
--i;
break;
}
printf( "Allocated %u at %Fp\n", _msize( p[i] ), (void _far *)p[i] );
}
/* Fill all free blocks with the test character. */
heapstat( _heapset( 254 ) );
/* In a real program, you might do operations here on the allocated
* buffers. Then do heapvalidate to make sure none of the operations
* wrote to free blocks.
*/
perr = heapvalidate( 254 );
if( perr == NULL )
printf( "Free entries are unchanged.\n\n" );
else
printf( "Free entry at %Fp modified.\n\n", perr );
/* Do some more heap operations. */
for( ; i >= 0; i-- )
{
free( p[i] );
printf( "Deallocating %u at %Fp\n",
_msize( p[i] ), (void _far *)p[i] );
}
/* Check heap again. */
heapstat( _heapchk() );
}
/* Tests each block in the heap. If a modified free block is found,
* returns it's address. Otherwise returns NULL.
*/
int _far *heapvalidate( char fill )
{
struct _heapinfo hi;
unsigned heapstatus, i;
char _far *p;
/* Walk through entries, checking free blocks. */
hi._pentry = NULL;
while( (heapstatus = _heapwalk( &hi )) == _HEAPOK )
{
/* For free entries, check each byte to see that it still has
* only the fill character. Return address if changed.
*/
if( hi._useflag != _USEDENTRY )
{
for( p = (char _far *)hi._pentry, i = 0; i < hi._size; p++,i++ )
if( (char)*p != fill )
return hi._pentry;
}
}
return NULL;
}
/* Reports on the status returned by _heapwalk, _heapset, or _heapchk */
void heapstat( int status )
{
printf( "\nHeap status: " );
switch( status )
{
case _HEAPOK:
printf( "OK - heap is fine" );
break;
case _HEAPEMPTY:
printf( "OK - empty heap" );
break;
case _HEAPEND:
printf( "OK - end of heap" );
break;
case _HEAPBADPTR:
printf( "ERROR - bad pointer to heap" );
break;
case _HEAPBADBEGIN:
printf( "ERROR - bad start of heap" );
break;
case _HEAPBADNODE:
printf( "ERROR - bad node in heap" );
break;
}
printf( "\n\n" );
}