PRODUCT : Borland C++ NUMBER : 1723
VERSION : All
OS : DOS
DATE : October 25, 1993 PAGE : 1/5
TITLE : Function that returns the total heap memory
/* HEAPMEM:
Function to return the total amount of memory on the heap.
You cannot use coreleft alone because it will only return
space from the top of DOS memory down to the last allocated
block. If any space has been freed below that last block, but
the last block is still in use, then coreleft will not
report on the free blocks in this space. The answer is to use
heapwalk in combination with coreleft. heapwalk gets
all the free blocks below the last allocated block, then
coreleft reports on the rest.
Tested with Borland C++ 3.1. Can be compiled for any memory
model.
*/
/* Define HEAP_DEBUG when testing fheapmem as a stand-alone
application.
*/
#define HEAP_DEBUG
#include
#include
#include
unsigned long heap_avail;
long cl,
smallest,
largest;
/* Add this function to your code. Use it instead of coreleft
to determine the total amount of heap available, including
the heap below the last allocated block. This function also
sets its parameters to the coreleft and the size of the
smallest and largest blocks available on the heap. Return
code less than zero means a heap error has been detected
(the negative of return code of heapwalk). A positive
return value is the number of bytes available on heap.
NOTE: You may leave off the parameters in your version of the
fheapmem function. They are not needed to complete the
functionality of fheapmem, they are only used here for
PRODUCT : Borland C++ NUMBER : 1723
VERSION : All
OS : DOS
DATE : October 25, 1993 PAGE : 2/5
TITLE : Function that returns the total heap memory
an example of what you may do.
*/
long fheapmem (long *cl, long *smallest, long *largest)
{
struct farheapinfo fhi;
unsigned long ret;
int hstat;
assert (farheapcheck() != _HEAPCORRUPT);
*cl = *largest = *smallest = ret = farcoreleft();
/* Add up all free nodes under last allocated block.
*/
fhi.ptr = NULL;
if ((hstat = farheapwalk (&fhi)) == _HEAPOK)
{
do
{
if (!fhi.in_use)
{
*smallest = fhi.size < *smallest ? fhi.size : *smallest;
*largest = fhi.size > *largest ? fhi.size : *largest;
ret += fhi.size;
}
} while ((hstat = farheapwalk (&fhi)) == _HEAPOK);
}
if (hstat == _HEAPCORRUPT) ret = -hstat;
return (ret);
}
#ifdef __COMPACT__ || __LARGE__ || __HUGE__
/* There is only far heap in these models.
*/
#define heapmem fheapmem
#else
/* For near models provide a heapmem which works on near heap.
PRODUCT : Borland C++ NUMBER : 1723
VERSION : All
OS : DOS
DATE : October 25, 1993 PAGE : 3/5
TITLE : Function that returns the total heap memory
*/
long heapmem (long *cl, long *smallest, long *largest)
{
struct heapinfo hi;
unsigned long ret;
int hstat;
assert (heapcheck() != _HEAPCORRUPT);
*cl = *largest = *smallest = ret = coreleft();
/* Add up all free nodes under last allocated block.
*/
hi.ptr = NULL;
if ((hstat = heapwalk (&hi)) == _HEAPOK)
{
do
{
if (!hi.in_use)
{
*smallest = hi.size < *smallest ? hi.size : *smallest;
*largest = hi.size > *largest ? hi.size : *largest;
ret += hi.size;
}
} while ((hstat = heapwalk (&hi)) == _HEAPOK);
}
if (hstat == _HEAPCORRUPT) ret = -hstat;
return (ret);
}
#endif
void show (char *str, long ha, long cl, long sm, long la)
{
printf ("%s %6ld %12ld %11ld %8ld\n", str, ha, cl, sm, la);
}
#ifdef HEAP_DEBUG
/* main demonstrates use of heapmem.
*/
PRODUCT : Borland C++ NUMBER : 1723
VERSION : All
OS : DOS
DATE : October 25, 1993 PAGE : 4/5
TITLE : Function that returns the total heap memory
void main (void)
{
unsigned long heap_avail = 0;
char *ba[100];
char *la[10];
int i;
long cl, smallest, largest;
printf ("* indicates where coreleft alone doesn't show "
"newly freed memory\n");
printf (" "
"heapmem farcoreleft SMALLEST LARGEST\n");
printf ("===================================================="
"=======================\n");
heap_avail = heapmem (&cl, &smallest, &largest);
show ("heap at start: ", heap_avail, cl,
smallest, largest);
/* Allocate some heap.
*/
for (i = 0; i < 10; i++)
la[i] = (char *) malloc (10);
heap_avail = heapmem (&cl, &smallest, &largest);
show ("heap after first allocation: ", heap_avail, cl,
smallest, largest);
/* Allocate more memory on heap.
*/
for (i = 0; i < 100; i++)
ba[i] = (char *) malloc (10);
heap_avail = heapmem (&cl, &smallest, &largest);
show ("heap after second allocation:*", heap_avail, cl,
smallest, largest);
/* Now free first allocation, thereby creating an area below
last allocation that coreleft will not report on as free
memory. This is where, using coreleft alone, it looks
as if your memory didn't get freed.
PRODUCT : Borland C++ NUMBER : 1723
VERSION : All
OS : DOS
DATE : October 25, 1993 PAGE : 5/5
TITLE : Function that returns the total heap memory
*/
for (i = 0; i < 10; i++)
free (la[i]);
heap_avail = heapmem (&cl, &smallest, &largest);
show ("heap after first release: *", heap_avail, cl,
smallest, largest);
/* Free up the rest of memory we allocated on heap. Now
coreleft is the same as heapmem because there are no
'holes' below the last allocated block of heap.
*/
for (i = 0; i < 100; i++)
free (ba[i]);
heap_avail = heapmem (&cl, &smallest, &largest);
show ("heap at end: ", heap_avail, cl,
smallest, largest);
}
#endif HEAP_DEBUG
DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.