







          1.
          1.
          1.   Introduction
               Introduction
               Introduction


          MoreHeap is a direct binary replacement of your compiler's far

          heap manager.  Depending on which compiler you use, it provides a

          smarter, a more robust, and a more space efficient heap manager.


          How does MoreHeap work?


               .    ________ __ _________ ___ _____ ___________ _______
                    MoreHeap is optimized for space efficiency, without

                    ___________ ______
                    sacrificing speed.  MoreHeap is more efficient because

                    it eliminates heap fragmentation by coalescing free

                    blocks as soon as possible.  When an initial heap

                    allocation request fails most heap managers performance

                    significantly degrades as they begin coalescing free

                    space attempting to satisfy the allocation request.

                    Performance times may degrade by several orders of

                    magnitude. Often, by the time they attempt to coalesce

                    the free space the heap is hopelessly and inefficiently

                    fragmented. On the other hand, MoreHeap's method

                    maintains predictable and efficient performance over a

                    wide range of heap utilization strategies.


                    On our applications we have noticed anywhere from a 10%

                    to 20% improvement in heap utilization.  In other

                    words, if you had 350K of available heap space and you

                    were not using MoreHeap, you might gain an additional

                    70K of usable heap space by simply relinking with

                    MoreHeap.


                    This savings is highly variable. We make no guarantees

                    that you can yield similar savings. These savings are

                    directly related to the amount of available heap and

                    the programs use of the heap. For example, if your

                    program only allocates blocks-then you are not

                    fragmenting the heap. Heap fragmentation is most common

                    when there are many small allocations of various sizes

                    being made, freed, and reallocated frequently. If your

                    program fits into this category you many be able to

                    yield significant savings. Further, to the extent you

                    have already recognized and dealt with the heap

                    fragmentation phenomena there is less of an opportunity

                    for MoreHeap to assist.




          MoreHeap                                  Reference Manual  1


               .    ________ ___ ____ _____ ___________ ___ __ _____ _____
                    MoreHeap can find extra addressable RAM on video cards

                    ___ _____ ________
                    and other devices.  The 8088 is limited to 1MB of

                    addressable memory and DOS is given control of 640K of

                    this addressable space.  Hence your far heap manager,

                    since it relies on DOS, is limited to 640K of total

                    space.  But if you have hardware-based expanded memory,

                    EGA or VGA video cards you have additional addressable

                    memory within this 1MB limit.  For example, a 256K VGA

                    card in an 80X25 text mode has 60K of usable RAM.  An

                    unused expanded memory card has 64K of usable RAM.

                    MoreHeap searches out this additional memory and

                    provides it to your C application as part of the normal

                    heap management process.


               .    ________ ___ ____ ____ ___ _____________________
                    MoreHeap can work with the Lotus/Intel/Microsoft

                    ________ ______ _____________ _____ __ _______ __
                    eXtended Memory Specification (XMS) to provide an

                    __________ ___ __ ___________ ______ __ ___ ___ ___
                    additional 64K of addressable memory on 286 and 386

                    _________
                    machines.


               .    If the above solutions are still inadequate and

                    protected mode is not an option you will have to use

                    virtual memory. This is not as attractive a solution

                    because more extensive reprogramming can be involved.

                    However, to ease the pain, ________ ________ _ _______
                                               MoreHeap provides a virtual

                    ______ _______ _____
                    memory manager (VMM) with a C-like interface. The VMM

                    works with the replacement far heap manager to provide

                    access to up 128MB of virtual memory. The virtual

                    memory manager will initially satisfy its requests from

                    DOS, with automatic overflow to expanded memory, then

                    to extended memory, and  finally, if extended memory is

                    insufficient, overflow is directed to disk.


                    Many virtual memory managers require your application

                    to set aside both swap-in and swap-out areas

                    Regardless of whether or not you require any virtual

                    memory at a particular point you have lost those

                    resources and may only access them through the virtual

                    memory manager. But, MoreHeap dynamically allocates

                    swap-in, and swap-out, space based on current

                    requirements with no intervention from the application

                    program.  Anywhere from 0% to 100% of addressable RAM

                    can be dynamically allocated to swap space. If

                    addressable memory requirements are low and virtual

                    memory requirements are high the entire heap will

                    automatically be used as swap space, improving

                    performance. If the reverse is true swap space will be

                    minimized and your application will have more

                    addressable memory than under a fixed swap space

                    scheme.








                                          2




          MoreHeap                                  Reference Manual  1


                    Because MoreHeap is a true far heap replacement library

                    and because it contains a virtual memory manager it

                    allows addressable heap and virtual heap to cooperate

                    much more closely than in simpler virtual memory

                    managers.  For example, all of the heap verification,

                    reporting and debugging routines work through the

                    entire heap, including the addressable and virtual

                    memory blocks.  Furthermore, as you request additional

                    memory through malloc(), for example, MoreHeap will

                    automatically swap out virtual memory blocks on demand

                    to create addressable space.


               .    ________ ________ ___________ _________ ________
                    MoreHeap contains alternative debugging routines that

                    will allow you to track access to the heap and

                    periodically check it for integrity.  You can compile

                    with or without debugging with a simple command line

                    switch to your compiler.








































                                          3




          MoreHeap                                  Reference Manual  2



          2.
          2.
          2.   System Requirements
               System Requirements
               System Requirements


          MoreHeap requires an IBM PC, PC-XT, PC-AT, PS/2, or close

          compatible running MS-DOS or PC-DOS version 3.1 or higher.


          MoreHeap has additional capabilities which can be used only on PC

          compatibles with 80286 and 80386 processors and memory above 1MB.

















































                                          4




          MoreHeap                                  Reference Manual  3



          3.
          3.
          3.   Installation
               Installation
               Installation


          To install MoreHeap copy the appropriate library, header files,

          and the himem.sys device driver to your computer.  Which files to

          copy depends on the compiler you are using.  We recommend you

          install MoreHeap as follows:


          Libraries:


          COPY D:\CCC\*.lib libpath
          COPY D:\CCC\*.lib libpath
          COPY D:\CCC\*.lib libpath


          CCC  = Your compiler manufacturer, MC6, TCP, TC2, or AZT.

          D    = Floppy disk drive containing the distribution disk.

          libpath   = You compiler's RTL directory


          COPY D:\CCC\*.h incpath
          COPY D:\CCC\*.h incpath
          COPY D:\CCC\*.h incpath


          Header files:


          CCC  = Your compiler manufacturer, MC6, TCP, TC2, or AZT.

          D    = Floppy disk drive containing the distribution disk.

          incpath   = You compiler's header files directory


          HIMEM.SYS:


          COPY SD:\XMS\HIMEM.SYS DD:\
          COPY SD:\XMS\HIMEM.SYS DD:\
          COPY SD:\XMS\HIMEM.SYS DD:\


          SD:       = Floppy disk drive containing the distribution disk.

          DD   = boot disk drive.


          And, add this line to config.sys:


          device = himem.sys /NUMHANDLES=128
          device = himem.sys /NUMHANDLES=128
          device = himem.sys /NUMHANDLES=128


          The source files are located in the SOURCE subdirectory in a

          self-unarchiving file, SOURCE.EXE. Some additional XMS files are

          included in the XMS directing in a self unarchiving file XMS.EXE.



















                                          5




          MoreHeap                                  Reference Manual  4



          4.
          4.
          4.   Glossary
               Glossary
               Glossary


          Expanded Memory refers to add-in memory accessed through an

                          expanded memory manager.


          Extended Memory refers to memory above 1MB that can be found on

                          some 80286 and 80386 machines.


          Heap            refers to memory available to your program, or

                          obtained by your program, from malloc, calloc, or

                          realloc.


          Page            every allocation from the heap belongs to a given

                          page.  Although your application will not

                          directly manipulate pages the term is used

                          throughout the documentation to explain various

                          processes.


          XMS             the Lotus/Intel/Microsoft eXtended Memory

                          Specification.


          EMS             The Lotus/Intel/Microsoft Expanded Memory

                          Specification.


          Handle          the virtual memory manager deals with "handles."

                          Handles cannot be used like pointers.  You must

                          explicitly dereference a handle to obtain a valid

                          pointer.




























                                          6




          MoreHeap                                  Reference Manual  5



          5.
          5.
          5.   Compatibility
               Compatibility
               Compatibility


          MoreHeap works with Turbo C 2.0, TC++ 1.0, Microsoft C 5.1,

          Microsoft C 6.0, and Aztec C86 4.1.  Although each of these

          compilers provides a standard set of heap management functions,

          each also provides some unique heap management functions.

          MoreHeap provides something close to a superset of all of these

          compilers' RTL heap management functions.  The following list of

          MoreHeap's functions indicates:


               .    functions which are supported by MoreHeap (signified by

                    an O.)


               .    functions which  are supported, but have some

                    differences with the original manufacturer's

                    implementation (signified by a D.)  Most differences

                    refer to support for virtual memory and support for

                    memory blocks greater than 64K.


               .    functions supported by MoreHeap which are not supported

                    by the manufacturers RTL (signified by an X.)  In these

                    cases a function name was used for the specific

                    compiler which matched the naming conventions used by

                    the compiler.
































                                          7




          MoreHeap                                  Reference Manual  5


                           T  T B  M A                   T  T B  M A

                           C  C C  S Z                   C  C C  S Z

                           2  + +  C T                   2  + +  C T

                              + +  5 4                      + +  5 4

                                   & .                           & .

            Function               6 1  Function                 6 1


            malloc         O  O O  O O  heapwalk         X  D D  D X

            farmalloc      O  O O       farheapwalk      X  D D

            _fmalloc               O X  _fheapwalk               D X

            _hmalloc               X X  free             O  O O  O O

            calloc         O  O O  O O  farfree          O  O O

            farcalloc      O  O O       _ffree                   O X

            _fcalloc               O X  heapfillfree     X  D D

            _hcalloc               X X  farheapfillfree  X  D D

            realloc        O  O O  O O  _heapset                 D X

            farrealloc     O  O O       _fheapset                D X

            _frealloc              O X  heapcheckfree    X  D D

            _hrealloc              X X  farheapcheckfree X  D D


            heapheck       X  O O       _heapchkfree             D X

            farheapcheck   X  O O       _fheapchkfree            D X

            heapchk                O X  heapchecknode    X  D D

            _fheapchk              O X  farheapchecknode X  D D

            msize          X  X X  D X  _heapchknode             D X

            farmsize       X  X X       _fheapchknode            D X

            _fmsize                D X  coreleft         O  O O  O X

            expand         X  X X  O X  farcoreleft      D  D D

            farexpand      X  X X       _fcoreleft               D X

            _fexpand               O X  farmemavl        X  X X

            _hexpand               X X  _fmemavl                 X X



          To use any function not supported by your original compiler you

          will need to #include the MoreHeap include file, "HEAP.H" in

          source files which reference MoreHeap specific functions.





















                                          8




          MoreHeap                                  Reference Manual  6



          6.
          6.
          6.   Using the MoreHeap far heap manager
               Using the MoreHeap far heap manager
               Using the MoreHeap far heap manager


          To begin using the replacement heap manager just relink your

          application with MHCCCM.lib.  M refers to the (S)mall or (L)arge

          model, and CCC refers to the C compiler, MC6 (Microsoft C 5.1 or

          6.0), TC2 (Turbo C 2.X), TCP (TC++ 1.0, and Borland C++ 1.0), or

          AZT (Aztec C86 4.10).  For example, to create the sample program

          test1.c using TC2 under the small memory model at the dos prompt

          type:


          TCC TEST1.C MHTC2S.LIB
          TCC TEST1.C MHTC2S.LIB
          TCC TEST1.C MHTC2S.LIB


          For MSC users type:


          CL TEST1.C MHMC6S.LIB LLIBCE.LIB /link /NOD /NOE
          CL TEST1.C MHMC6S.LIB LLIBCE.LIB /link /NOD /NOE
          CL TEST1.C MHMC6S.LIB LLIBCE.LIB /link /NOD /NOE


          Aztec users type:


          CC TEST1.C MHAZTS.LIB
          CC TEST1.C MHAZTS.LIB
          CC TEST1.C MHAZTS.LIB


          While relinking provides certain immediate benefits, MoreHeap has

          many features (if you choose to use them).  In order to use the

          heap manager to its fullest extent you will need to enable some

          of its special capabilities.


          MoreHeap's capabilities fall into 6 categories:


               .    regular DOS memory


               .    memory from EGA and VGA video cards


               .    memory from expanded memory cards


               .    upper memory blocks (UMBs) supplied by an XMS

                    compatible driver, like DOS 5.0's EMM386 and

                    Quarterdeck's QEMM-386.


               .    the high memory area (0xFFFF:0x0010 -- 0xFFFF:0xFFFF)

                    supplied by an XMS compatible driver, like HIMEM.SYS.


               .    virtual memory


          The replacement manager initially only utilizes DOS by default.

          Because MoreHeap is a more space efficient heap manager you are

          immediately provided with certain benefits simply by relinking.

          However, in order to use these additional memory resources you

          must insert this statement into your main() function:

          mhenable(SOURCE).


          Where SOURCE can be DOS, VID, EMM, UMB, or HMA.  (These choices

          correspond to the special capabilities noted above and are

          defined as constants in the MoreHeap include file, "HEAP.H")




                                          9




          MoreHeap                                  Reference Manual  6


          For example:


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>

          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               .
               .
               .

               .
               .
               .

               .
               .
               .

               mhenable ( VID );
               mhenable ( VID );
               mhenable ( VID );

               mhenable ( EMM );
               mhenable ( EMM );
               mhenable ( EMM );

               mhenable ( HMA );
               mhenable ( HMA );
               mhenable ( HMA );

               .
               .
               .

               .
               .
               .

               .
               .
               .

          }
          }
          }








































                                         10




          MoreHeap                                  Reference Manual  6



          6.1.
          6.1.
          6.1. Special considerations
               Special considerations
               Special considerations


          MoreHeap has additional overhead which could negate its benefits.

          In most cases MoreHeap will provide some, if not a significant,

          benefit. MoreHeap overhead is incurred in two ways:


               1.   MoreHeap has a 5 byte per allocation overhead, Turbo-C

                    has a 4 byte per allocation overhead, and Microsoft C

                    has a 2 byte per allocation overhead.


               2.   The MoreHeap libraries are larger. Based on the

                    functions you link in your executable size will

                    increase about


                    500 bytes      quick'n'dirty heap extender


                    4K             far heap manager (DOS 5 UMBs supported)


                    8K             far heap manager with 640K-1MB features


                    12K            far heap and virtual memory manager


                    You may see a larger increase if you are using certain

                    debug functions such as far heapcheck() or _fheapchk().

                    MoreHeap has more internal consistency checks to make

                    and these functions operate with both the far heap and

                    the virtual heap. Hence our versions are somewhat

                    larger. These functions are not typically included in a

                    finished product however.


          MoreHeap typically makes up for the added overhead in these ways


               1.   Turbo-C allocates on paragraph boundaries (multiples of

                    16 bytes.) MoreHeap allocates on byte boundaries. If

                    you have lots of allocations of varying sizes Turbo-C

                    will have an average of 8 bytes of wasted space in each

                    allocation.


               2.   MoreHeap tends to reduce heap fragmentation by

                    coalescing free blocks as soon as possible. This often

                    increases the amount of usable heap in an application

                    that allocates and deallocates lots of blocks.


               3.   MoreHeap is about 15% faster on straight allocations

                    than Microsoft C, a little slower than Turbo-C.

                    MoreHeap is faster than both on reallocations.


               4.   Potential to access up to 344K of memory within the

                    640K to 1MB region.


          MoreHeap is incompatible with some versions of the spawn??()

          family of functions. If your application uses spawn you must use

          the MoreHeap replacement function for spawnlp()-mhloadprog().



                                         11




          MoreHeap                                  Reference Manual  6


          MoreHeap is incompatible with most version of the exec??() family

          of functions. These functions make certain assumptions about how

          the program has allocated memory from DOS. (In fact if you

          directly allocate memory from DOS, whether or not you use

          MoreHeap, your program is probably incompatible with exec.) In

          order for exec??() to operate properly all DOS memory allocated

          by MoreHeap must be returned to DOS. The mhexit() function will

          deallocate all DOS memory, and all other resources used by

          MoreHeap. Immediately prior to calling exec??() call mhexit() and

          exec??() will operate properly.


          MoreHeap is VROOMM safe (compiled with the -Y switch) but you

          must not overlay MoreHeap itself.


          When deciding to "enable" additional MoreHeap resources you will

          need to consider the following limitations.









































                                         12




          MoreHeap                                  Reference Manual  6


          6.1.1.
          6.1.1.
          6.1.1.    VID
                    VID
                    VID


          Video can use up to 60K of RAM on 128K EGA and VGA cards, but by

          default, it will only use 16K of video ram.  In 80 X 25 text mode

          each video page takes 4K and MoreHeap allows your application

          access to the first four pages. You can change the amount of

          memory reserved for the application's video output by changing

          the value of VID_reserve to the number of bytes of video ram you

          want to set aside.  VID_reserve is initially set at 16K.


          You can use up to 60K of video ram using a more aggressive

          technique by including these statements in your main() function:


          mhenable(VID);
          mhenable(VID);
          mhenable(VID);           /* allocate heap out of video ram */
                                   /* allocate heap out of video ram */
                                   /* allocate heap out of video ram */

          VID_safe = 0;
          VID_safe = 0;
          VID_safe = 0;            /* aggressive technique flag */
                                   /* aggressive technique flag */
                                   /* aggressive technique flag */

          VID_reserve = 4096;
          VID_reserve = 4096;
          VID_reserve = 4096;      /* set aside one video page for app */
                                   /* set aside one video page for app */
                                   /* set aside one video page for app */

          VID_init();
          VID_init();
          VID_init();              /* reset video card */
                                   /* reset video card */
                                   /* reset video card */


          This technique has four limitations that you will need to be

          aware of.


               .    The technique  will only work in text modes.


               .    In order to use this technique MoreHeap reprograms the

                    video card to display the first text page starting at

                    0xA000:0x0000.  Usually the first text page is at

                    0xB800:0x0000.  Once the card is reprogrammed the bios

                    and dos based video output routines such as puts() and

                    printf() will no longer work. Turbo C's cputs() and

                    cprintf(), however, will continue to work.


               .    Many PC-based programs directly access video ram for

                    screen i/o.  In this case, to use the more aggressive

                    technique, change the value of the variable containing

                    the pointer to video RAM from 0xB800:0x0000 to

                    0xA000:0x0000.  In addition, since Each RAM source

                    performs its initialization at the time that it is

                    needed and because this technique resets the video card

                    you will probably want to reset the video card in

                    advance with a call to VID_init().


               .    Access to video ram, using this technique, is not

                    arbitrated by a device driver such as HIMEM.SYS.  Do

                    not use this approach in conjunction with any programs

                    which also use uncooperative methods for accessing

                    video ram.  This includes, other programs using

                    MoreHeap with the VID technique, LOADHI.SYS, and

                    others.


          As an alternative to including the mhenable(VID) statement in

          your program and recompiling. You can declare an environment

          variable, VIDRAM, and assign it a value of YES. To do this type

          the following at the command line:




                                         13




          MoreHeap                                  Reference Manual  6


          SET VIDRAM=YES
          SET VIDRAM=YES
          SET VIDRAM=YES



          This will immediately provide your program with 16K of additional

          RAM--provided your program only operates in text modes.




















































                                         14




          MoreHeap                                  Reference Manual  6


          6.1.2.
          6.1.2.
          6.1.2.    EMM
                    EMM
                    EMM


          The EMM technique will use the 64K window of an expanded memory

          manager as part of the heap. DO NOT USE THIS FEATURE IF YOU ARE

          MAKING ANY OTHER USE OF EXPANDED MEMORY WITHIN THE PROGRAM.  DO

          NOT USE THIS FEATURE IF YOU "spawn" PROGRAMS WHICH MANIPULATE

          EXPANDED MEMORY. DO NOT USE THIS FEATURE IF YOU USE THE VIRTUAL

          MEMORY MANAGER.


          If you include mhenable(EMM) in you program you must exit via

          exit() or call mhexit() before terminating in order to release

          the expanded memory allocated by MoreHeap.


          If your program exits via a call to exit() you can use this

          technique with out including the mhenable(EMM) statement in your

          program by declaring an environment variable, EMMFRAME and

          setting it to YES like this.


          SET EMMFRAME=YES
          SET EMMFRAME=YES
          SET EMMFRAME=YES






































                                         15




          MoreHeap                                  Reference Manual  6


          6.1.3.
          6.1.3.
          6.1.3.    UMB
                    UMB
                    UMB


          The UMB technique will request "upper memory blocks" from an XMS

          compatible device driver such as HIMEM.SYS.  (See the

          Lotus/Intel/Microsoft eXtended Memory Specification for further

          discussion of upper memory blocks.)


          The version of HIMEM.SYS distributed with this version of

          MoreHeap does not support the upper memory block feature.


          HIMEM.SYS will only operate on '286 or '386 machines.


          The most common source of UMBs is DOS 5.0's EMM386 and QEMM-386.

          (UMBs are only available on '386 and '486 machines.) If using

          EMM386 do not include this line in you config.sys file:


          DOS=HIGH,UMB
          DOS=HIGH,UMB
          DOS=HIGH,UMB


          This will allocate ALL UMBs to DOS at startup. MoreHeap will not

          be able use them. This is OK, however.


          DOS=HIGH
          DOS=HIGH
          DOS=HIGH


          If you include the statement mhenable(UMB) your program must

          terminate via exit() or call mhexit() before terminating to

          release the UMBs. If you do not do this the UMBs will be

          unusable, and orphaned. To restore the UMBs you must reboot.


          If your program terminates via exit() you can include UMBs

          without reprogramming by setting an environment variable UMB to

          YES, like this:


          SET UMB=YES
          SET UMB=YES
          SET UMB=YES
























                                         16




          MoreHeap                                  Reference Manual  6


          6.1.4.
          6.1.4.
          6.1.4.    HMA
                    HMA
                    HMA


          The HMA technique will request the "high memory area" from an XMS

          compatible device driver such as HIMEM.SYS.  (See the

          Lotus/Intel/Microsoft eXtended Memory Specification for further

          discussion of the high memory area.)


          HIMEM.SYS requires a '286 or '386 machine and the high memory

          area requires RAM above 1MB.


          Pointers from this area will have a segment value of 0xFFFF.

          Although the processor will manipulate pointers with a segment of

          0xFFFF, unfortunately, DOS will "normalize" the pointer.


          Normalizing a pointer refers to dividing the offset by 16 and

          then adding the result to the segment and assigning the remainder

          to the offset.  This guarantees that every possible segment that

          could be represented by a normalized pointer refers to a unique

          16 byte area in addressable memory.  Pointers are usually

          normalized in order to compare them and determine if one comes

          before or after another pointer within addressable memory.


          Usually, normalizing a pointer has no effect on what the pointer

          references.  But in the case of a pointer with a segment value of

          0xFFFF this is not always true.  For example, if you were to

          normalize the pointer 0xFFFF:0x0010, by dividing the offset

          0x0010 by 16 the result would be 1 with no remainder.  Adding the

          result (1) to the segment 0xFFFF would yield a normalized segment

          of 0x0000 (the value should be 0x10000, but this value exceeds

          the allotted storage size and the high bit is lost.)  You

          construct the normalized pointer by joining the normalized

          segment and the remainder (0), yielding a pointer value of

          0x0000:0x0000. As you can see, in this case normalizing the

          pointer has modified what the pointer references.


          Never pass a pointer coming from the high memory area to a DOS

          function.  The most common DOS call to watch for is a ____ ____
                                                                disk read

          ____ _ ______
          into a buffer.  Therefore, if you have enabled HMA you should

          surround certain calls with:


          mhdisable(HMA);
          mhdisable(HMA);
          mhdisable(HMA);

          ...
          ...
          ...

          mhenable(HMA);
          mhenable(HMA);
          mhenable(HMA);


          The most obvious examples where this would be necessary are,

          fopen() (because it allocates its own read/write buffer) and any

          allocations of buffers which could be passed to a read() or a

          write() call.


          As an alternative you could not mhenable(HMA) within main(), but

          identify "safe" heap intensive areas and surround these with the

          same calls, but in opposite directions:





                                         17




          MoreHeap                                  Reference Manual  6


          mhenable(HMA);
          mhenable(HMA);
          mhenable(HMA);

          ...
          ...
          ...

          mhdisable(HMA);
          mhdisable(HMA);
          mhdisable(HMA);


          If you are using DOS 5.0 and have the line


          DOS=HIGH
          DOS=HIGH
          DOS=HIGH


          in your config.sys file, the HMA is already in use by DOS and

          cannot be used by your program. Since MoreHeap can use all 64K of

          the HMA and DOS only uses about half of the space you may find

          that you ultimately get more heap space by removing the DOS=HIGH

          line from your config.sys file.


          If you include the statement mhenable(HMA) your program must

          terminate via exit() or call mhexit() before terminating to

          release the HMA. Otherwise, the HMA will not be usable by

          subsequent programs. To restore the HMA you must reboot.


          Provided your application meets the above criteria you can enable

          the HMA facility without reprogramming by setting an environment

          variable HIGHMEM to YES, like this:


          SET HIGHMEM=YES
          SET HIGHMEM=YES
          SET HIGHMEM=YES

































                                         18




          MoreHeap                                  Reference Manual  6


          6.1.5.
          6.1.5.
          6.1.5.    Summary
                    Summary
                    Summary


          You can immediately use MoreHeap to minimize heap fragmentation

          by just relinking, provided your program does not use exec??() or

          spawn??(). If your program uses exec??() immediately precede the

          call to exec??() with a call to mhexit(). If your program uses

          spawn??() you must replace the calls to spawn with mhloadprog().

          Remember, mhloadprog uses the spawnlp() syntax, not spawnvp() or

          any other members of the spawn family.


          You can also use upper memory blocks, the high memory area, video

          ram, and the expanded memory manager's page frame, by just

          relinking, by declaring these environment variables--with the

          following limitations.


          SET UMB=YES         Program must terminate via exit()


          SET VIDRAM=YES      Program must not use graphics modes


          SET EMMFRAME=YES    Program does not use expanded memory and must

                              exit via exit().


          SET HIGHMEM=YES     Probably not feasible given the limitations

                              on DOS usage, but if your program does not

                              have a lot of disk i/o or otherwise interact

                              heavily with DOS you might try it. Your

                              program must also terminate via exit().






























                                         19




          MoreHeap                                  Reference Manual  6



          6.2.
          6.2.
          6.2. Functions & Globals
               Functions & Globals
               Functions & Globals


          In many cases MoreHeap is simply providing a replacement function

          for your compiler's original RTL routines.  In those cases __
                                                                     NO

          _______ __ ____ __ _________ ___ ___________ _____ __ ____
          attempt is made to duplicate the information found in your

          __________ ___ _________
          compiler's RTL reference.  In these situations the manual simply

          provides information on compatibility with your compiler's RTL.

















































                                         20




          MoreHeap                                  Reference Manual  6


          6.2.1.
          6.2.1.
          6.2.1.    amblksiz
                    amblksiz
                    amblksiz


          Determines the size of pages requested from DOS, virtual memory,

          and other sources.  This value is used differently than under MSC

          (TC has no comparable variable.)


          When MoreHeap cannot satisfy a memory allocation request from an

          existing page it will request a new page.  The initial request

          will round up the requested memory to a multiple of amblksiz and

          request a page of the rounded up size.  If it is unable to

          allocate a page of that size it will then attempt to allocate a

          page of the exact size of the memory request, failing that, if

          virtual memory is active it will start swapping out pages until

          it can satisfy the page allocation request in RAM.


          The default for amblksiz is 8K.









































                                         21




          MoreHeap                                  Reference Manual  6


          6.2.2.
          6.2.2.
          6.2.2.    calloc, _fcalloc, _hcalloc, farcalloc
                    calloc, _fcalloc, _hcalloc, farcalloc
                    calloc, _fcalloc, _hcalloc, farcalloc


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          void far *calloc ( size_t nbytes )
          void far *calloc ( size_t nbytes )
          void far *calloc ( size_t nbytes )

          void far *_fcalloc ( size_t nbytes )
          void far *_fcalloc ( size_t nbytes )
          void far *_fcalloc ( size_t nbytes )


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void far *_hcalloc ( unsigned long nbytes )
          void far *_hcalloc ( unsigned long nbytes )
          void far *_hcalloc ( unsigned long nbytes )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>


          void far *calloc ( size_t nbytes )
          void far *calloc ( size_t nbytes )
          void far *calloc ( size_t nbytes )

          void far *farcalloc ( unsigned long nbytes )
          void far *farcalloc ( unsigned long nbytes )
          void far *farcalloc ( unsigned long nbytes )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          calloc()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _fcalloc


          _fcalloc()      Replacement for _fcalloc.


          _hcalloc()      Same as _fcalloc but will take an argument

                          greater than 64K up to 1MB (less 32 bytes.)


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          calloc()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to farcalloc (TC).


          farcalloc()     Replacement for farcalloc.


          ___________
          Description


          Returns a far pointer to the newly allocated memory block on

          success.  Returns NULL on failure.










                                         22




          MoreHeap                                  Reference Manual  6


          6.2.3.
          6.2.3.
          6.2.3.    coreleft, _fcoreleft, farcoreleft
                    coreleft, _fcoreleft, farcoreleft
                    coreleft, _fcoreleft, farcoreleft


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          unsigned long coreleft ( void )
          unsigned long coreleft ( void )
          unsigned long coreleft ( void )


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned long _fcoreleft ( void )
          unsigned long _fcoreleft ( void )
          unsigned long _fcoreleft ( void )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>


          unsigned long coreleft ( void )
          unsigned long coreleft ( void )
          unsigned long coreleft ( void )


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned long farcoreleft ( void )
          unsigned long farcoreleft ( void )
          unsigned long farcoreleft ( void )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          coreleft()      Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _fcoreleft.


          _fcoreleft()    No comparable function.  Returns the largest

                          available free block on the far heap.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          coreleft()      Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to farcoreleft().


          farcoreleft()   This is a replacement for the original RTL

                          function.


          Note that the disabled (via a call to mhdisable() resources are

          not included in the return value.


          ___________
          Description


          Returns the largest free block found, in bytes.







                                         23




          MoreHeap                                  Reference Manual  6


          6.2.4.
          6.2.4.
          6.2.4.    _expand, _fexpand, _hexpand, farexpand
                    _expand, _fexpand, _hexpand, farexpand
                    _expand, _fexpand, _hexpand, farexpand


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          void far * expand ( void far *p, size_t nbytes )
          void far * expand ( void far *p, size_t nbytes )
          void far * expand ( void far *p, size_t nbytes )

          void far * _fexpand ( void far *p, size_t nbytes )
          void far * _fexpand ( void far *p, size_t nbytes )
          void far * _fexpand ( void far *p, size_t nbytes )


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void far * _hexpand ( void far *p, unsigned long nbytes )
          void far * _hexpand ( void far *p, unsigned long nbytes )
          void far * _hexpand ( void far *p, unsigned long nbytes )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void far * expand ( void far *p, size_t nbytes )
          void far * expand ( void far *p, size_t nbytes )
          void far * expand ( void far *p, size_t nbytes )

          void far * farexpand ( void far *p, unsigned long nbytes )
          void far * farexpand ( void far *p, unsigned long nbytes )
          void far * farexpand ( void far *p, unsigned long nbytes )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          expand()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _fexpand().


          _fexpand()      Replacement for MSC's _fexpand.


          _hexpand()      Same as _fexpand but will take an argument

                          greater than 64K up to 1MB (less 32 bytes.)


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          expand()        TC has no comparable function.  Under large model

                          passes the call through to farexpand().


          farexpand()     TC has no comparable function.


          ___________
          Description


          This function is identical to realloc except that it will only

          return a pointer to the memory block if it can resize it without

          moving it.  For example, if it can takeover an adjacent free

          block.  Will only allocate a block up to 1MB (less 32 bytes.)

          Returns "p" on success, NULL on failure.








                                         24




          MoreHeap                                  Reference Manual  6


          6.2.5.
          6.2.5.
          6.2.5.    _fmemavl, farmemavl
                    _fmemavl, farmemavl
                    _fmemavl, farmemavl


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned long _fmemavl ( void )
          unsigned long _fmemavl ( void )
          unsigned long _fmemavl ( void )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned long farmemavl ( void )
          unsigned long farmemavl ( void )
          unsigned long farmemavl ( void )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _fmemavl()      MSC has no comparable function.



          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          farmemavl()     TC has no comparable function.



          ___________
          Description


          Returns the total amount of free far heap space.  The disabled

          memory resources are not included in the total.

























                                         25




          MoreHeap                                  Reference Manual  6


          6.2.6.
          6.2.6.
          6.2.6.    _fwriteprotect, farwriteprotect, mh_wp_enabled
                    _fwriteprotect, farwriteprotect, mh_wp_enabled
                    _fwriteprotect, farwriteprotect, mh_wp_enabled


          _____
          Usage


          _________ _ ___ _____ _
          Microsoft C and Aztec C
          _________ _ ___ _____ _
          Microsoft C and Aztec C
          _________ _ ___ _____ _
          Microsoft C and Aztec C


          #include "heap.h"
          #include "heap.h"
          #include "heap.h"


          void _fwriteprotect ( void far * p )
          void _fwriteprotect ( void far * p )
          void _fwriteprotect ( void far * p )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include "heap.h"
          #include "heap.h"
          #include "heap.h"


          void farwriteprotect ( void far *p )
          void farwriteprotect ( void far *p )
          void farwriteprotect ( void far *p )


          ___________
          Description


          Computes a checksum for the memory block pointed to by "p".

          Subsequent calls to farheapcheck() or _fheapchk() will recompute

          the checksum. If the contents of the memory block have been

          modified since the last call to farwriteprotect(p) a value of

          _HEAPBADCKSUM will be returned.


          farheapcheck()/_fheapchk() are relied on for both the _HEAPDEBUG

          and _HEAPTRACE modes and a _HEAPBADCKSUM error will terminate the

          application under these conditions.


          To use this function you must make this the first statement in

          main()


          int main()
          int main()
          int main()

          {
          {
          {

               mh_wp_enabled = 1;
               mh_wp_enabled = 1;
               mh_wp_enabled = 1;

               .
               .
               .

               .
               .
               .

          }
          }
          }




















                                         26




          MoreHeap                                  Reference Manual  6


          For example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int main()
          int main()
          int main()

          {
          {
          {

               char far *p;
               char far *p;
               char far *p;


               mh_wp_enabled = 1;
               mh_wp_enabled = 1;
               mh_wp_enabled = 1;            // enable write protect
                                             // enable write protect
                                             // enable write protect

               p = _fcalloc ( 1, 10 );
               p = _fcalloc ( 1, 10 );
               p = _fcalloc ( 1, 10 );       // allocate block
                                             // allocate block
                                             // allocate block

               _fwriteprotect ( p );
               _fwriteprotect ( p );
               _fwriteprotect ( p );         // write protect block
                                             // write protect block
                                             // write protect block

               mhheapdump();
               mhheapdump();
               mhheapdump();                 // get heap dump, no errs
                                             // get heap dump, no errs
                                             // get heap dump, no errs

               p[0]= 1;
               p[0]= 1;
               p[0]= 1;                      // modify block
                                             // modify block
                                             // modify block

               mhheapdump();
               mhheapdump();
               mhheapdump();                 // heap dump terminates with 
                                             // heap dump terminates with 
                                             // heap dump terminates with 

                                             // _HEAPBADCKSUM
                                             // _HEAPBADCKSUM
                                             // _HEAPBADCKSUM


          }
          }
          }







































                                         27




          MoreHeap                                  Reference Manual  6


          6.2.7.
          6.2.7.
          6.2.7.    free, _ffree, farfree
                    free, _ffree, farfree
                    free, _ffree, farfree


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          void free ( void far * )
          void free ( void far * )
          void free ( void far * )

          void _ffree ( void far * )
          void _ffree ( void far * )
          void _ffree ( void far * )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>


          void free ( void far * )
          void free ( void far * )
          void free ( void far * )

          void farfree ( void far * )
          void farfree ( void far * )
          void farfree ( void far * )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          free()          Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _ffree().


          _ffree()        Replacement for _ffree().  Also, frees blocks

                          allocated using the _hmalloc() MoreHeap function.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          free()          Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to farfree().


          farfree()       Replacement for TC's farfree.


          ___________
          Description


          Unlike the RTL version, will not free blocks unless marked as

          USED, i.e. will not corrupt the heap by freeing a block not

          allocate through malloc(). An attempt to free a FREE block will

          set the MoreHeap error flag to ISFREE. You can get the value of

          the MoreHeap error flag by calling mherr().













                                         28




          MoreHeap                                  Reference Manual  6


          6.2.8.
          6.2.8.
          6.2.8.    _heapchk, _fheapchk, heapcheck, farheapcheck
                    _heapchk, _fheapchk, heapcheck, farheapcheck
                    _heapchk, _fheapchk, heapcheck, farheapcheck


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int _heapchk ( void )
          int _heapchk ( void )
          int _heapchk ( void )

          int _fheapchk ( void )
          int _fheapchk ( void )
          int _fheapchk ( void )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int heapcheck ( void )
          int heapcheck ( void )
          int heapcheck ( void )

          int farheapcheck ( void )
          int farheapcheck ( void )
          int farheapcheck ( void )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _heapchk()      Under small model uses original RTL.  Under large

                          model passes call through to _fheapchk().


          _fheapchk()     Replaces original RTL function.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          heapcheck()     Under TC++ 1.0 small model uses original RTL.

                          Under large model passes call through to

                          farheapcheck().  No comparable function exists

                          for TC 2.X.


          farheapcheck()  Under TC++ replaces original RTL.  No comparable

                          function exists under TC 2.0.


          ___________
          Description


          Each call returns:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found (not possible-

                         indicates heap corrupted.)

          _HEAPBADCKSUM       A write protected block has been modified.

          _HEAPBUFOVWR        Write past the end of a buffer


          Any return values other than _HEAPOK indicate some sort of

          overwrite of heap memory.





                                         29




          MoreHeap                                  Reference Manual  6


          This function will walk through both the addressable and virtual

          memory blocks.























































                                         30




          MoreHeap                                  Reference Manual  6


          6.2.9.
          6.2.9.
          6.2.9.    _heapchkfree, heapcheckfree, _fheapchkfree,
                    _heapchkfree, heapcheckfree, _fheapchkfree,
                    _heapchkfree, heapcheckfree, _fheapchkfree,

          farheapcheckfree
          farheapcheckfree
          farheapcheckfree


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int _heapchkfree ( unsigned fill )
          int _heapchkfree ( unsigned fill )
          int _heapchkfree ( unsigned fill )

          int _fheapchkfree ( unsigned fill )
          int _fheapchkfree ( unsigned fill )
          int _fheapchkfree ( unsigned fill )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int heapcheckfree ( unsigned fill )
          int heapcheckfree ( unsigned fill )
          int heapcheckfree ( unsigned fill )

          int farheapcheckfree ( unsigned fill )
          int farheapcheckfree ( unsigned fill )
          int farheapcheckfree ( unsigned fill )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _heapchkfree()  Under small model uses original RTL.  Under large

                          model passes call through to _fheapchkfree().


          _fheapchkfree() Replaces original RTL function.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          heapcheckfree() Under TC++ 1.0 small model uses original RTL.

                          Under large model passes call through to

                          farheapcheckfree().  No comparable function

                          exists for TC 2.0.


          farheapcheckfree()  Under TC++ replaces original RTL.  No

                          comparable function exists under TC 2.0.


          ___________
          Description


          Checks all free nodes (both addressable and virtual) to see if

          their contents are filled with the value of "fill".


          Each call returns:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found

          _HEAPBADCKSUM       A write protected block has been modified

          _HEAPBUFOVWR        Write past the end of a buffer


          Block did not contain the fill value



                                         31




          MoreHeap                                  Reference Manual  6


          Any return values other than _HEAPOK indicate some sort of

          overwrite of heap memory.  Note that any heap function calls

          between a call to the heapset/heapfillfree routine and the

          heapchkfree/heapcheckfree routine can create additional free

          blocks which do not contain the "fill" value.  This situation

          would make the results from these routines not meaningful.



















































                                         32




          MoreHeap                                  Reference Manual  6


          6.2.10.
          6.2.10.
          6.2.10.   _heapchknode, _fheapchknode, heapchecknode,
                    _heapchknode, _fheapchknode, heapchecknode,
                    _heapchknode, _fheapchknode, heapchecknode,

          farheapchecknode
          farheapchecknode
          farheapchecknode


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int _heapchknode ( void far * p )
          int _heapchknode ( void far * p )
          int _heapchknode ( void far * p )

          int _fheapchknode ( void far * p )
          int _fheapchknode ( void far * p )
          int _fheapchknode ( void far * p )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int heapchecknode ( void far * p )
          int heapchecknode ( void far * p )
          int heapchecknode ( void far * p )

          int farheapchecknode ( void far * p )
          int farheapchecknode ( void far * p )
          int farheapchecknode ( void far * p )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _heapchknode()  Not used under small model.  Under large model

                          passes call through to _fheapchknode().


          _fheapchknode() No comparable function exists under MSC.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          heapchecknode() Under TC++ 1.0 small model uses original RTL.

                          Under large model passes call through to

                          farheapchecknode().  No comparable function

                          exists for TC 2.0.


          farheapchecknode()  Under TC++ replaces original RTL.  No

                          comparable function exists under TC 2.0.


          ___________
          Description


          Determines if "p" is a valid heap pointer.  A valid heap pointer

          can be either a pointer obtained from malloc (realloc, calloc,

          etc.) or a handle obtained from vmmalloc (vmrealloc, vmcalloc,

          etc.)  You must cast the handle to a pointer (not dereference it)

          to pass it as a parameter to this function.  For further

          discussion of the virtual memory manager see the section entitled

          "Using the virtual memory manager".










                                         33




          MoreHeap                                  Reference Manual  6


          Each call returns:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found

          _HEAPBADCKSUM       A write protected block has been modified

          _HEAPBUFOVWR        Write past the end of a buffer


          Any return values other than _HEAPOK indicate some sort of

          overwrite of heap memory, or that the pointer was not obtained

          through the heap interface functions.












































                                         34




          MoreHeap                                  Reference Manual  6


          6.2.11.
          6.2.11.
          6.2.11.   _heapset, heapfillfree,_fheapset, farheapfillfree
                    _heapset, heapfillfree,_fheapset, farheapfillfree
                    _heapset, heapfillfree,_fheapset, farheapfillfree


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int _heapset ( unsigned fill )
          int _heapset ( unsigned fill )
          int _heapset ( unsigned fill )

          int _fheapset ( unsigned fill )
          int _fheapset ( unsigned fill )
          int _fheapset ( unsigned fill )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int heapfillfree ( unsigned fill )
          int heapfillfree ( unsigned fill )
          int heapfillfree ( unsigned fill )

          int farheapfillfree ( unsigned fill )
          int farheapfillfree ( unsigned fill )
          int farheapfillfree ( unsigned fill )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _heapset()      Under small model uses original RTL.  Under large

                          model passes call through to _fheapset().


          _fheapset()     Replaces original RTL function.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          heapfillfree()  Under TC++ 1.0 small model uses original RTL.

                          Under large model passes call through to

                          farheapfillfree().  No comparable function exists

                          for TC 2.0.


          farheapfillfree()   Under TC++ replaces original RTL.  No

                          comparable function exists under TC 2.0.


          ___________
          Description


          Fills all free nodes in the heap (both addressable and virtual)

          with the value "fill"


          Each call returns:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found

          _HEAPBADCKSUM       A write protected block has been modified

          _HEAPBUFOVWR        Write past the end of a buffer


          Any return values other than _HEAPOK indicate some sort of

          overwrite of heap memory.



                                         35




          MoreHeap                                  Reference Manual  6


          6.2.12.
          6.2.12.
          6.2.12.   _heapstat
                    _heapstat
                    _heapstat


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          char * _heapstat ( int errcode );
          char * _heapstat ( int errcode );
          char * _heapstat ( int errcode );


          _____________
          Compatibility


          No comparable function exists under TC or MSC.


          ___________
          Description


          Maps the heap error codes to strings.  Returns a pointer to an

          appropriate string given one these error codes:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found

          _HEAPBADCKSUM       Write protected block has been modified

          _HEAPBUFOVWR        Write past the end of a buffer

          _HEAPEND            Last block in the heap



          For example:


          .
          .
          .

          .
          .
          .

          .
          .
          .

          printf("Heap error:%s\n",_heapstat ( _HEAPBADBEGIN ) );
          printf("Heap error:%s\n",_heapstat ( _HEAPBADBEGIN ) );
          printf("Heap error:%s\n",_heapstat ( _HEAPBADBEGIN ) );

          .
          .
          .

          .
          .
          .

          .
          .
          .





















                                         36




          MoreHeap                                  Reference Manual  6


          6.2.13.
          6.2.13.
          6.2.13.   _heapwalk, _fheapwalk, farheapwalk
                    _heapwalk, _fheapwalk, farheapwalk
                    _heapwalk, _fheapwalk, farheapwalk


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          int _heapwalk ( struct _heapinfo far * hinfo )
          int _heapwalk ( struct _heapinfo far * hinfo )
          int _heapwalk ( struct _heapinfo far * hinfo )

          int _fheapwalk ( struct _heapinfo far * hinfo )
          int _fheapwalk ( struct _heapinfo far * hinfo )
          int _fheapwalk ( struct _heapinfo far * hinfo )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int heapwalk ( struct farheapinfo far * hinfo )
          int heapwalk ( struct farheapinfo far * hinfo )
          int heapwalk ( struct farheapinfo far * hinfo )

          int farheapwalk ( struct farheapinfo far * hinfo )
          int farheapwalk ( struct farheapinfo far * hinfo )
          int farheapwalk ( struct farheapinfo far * hinfo )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _heapwalk()     Under small model uses original RTL.  Under large

                          model passes call through to _fheapchk().


          _fheapwalk()    Replaces original RTL function.


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          _heapwalk()     Under TC++ 1.0 small model uses original RTL.

                          Under TC large model passes call through to

                          farheapcheck().  No comparable function exists

                          for TC 2.0.


          farheapwalk()   Under TC++ replaces original RTL.  No comparable

                          function exists under TC 2.0.


          ___________
          Description


          Each call returns the next pointer in the heap in hinfo->_pentry

          (MSC) or hinfo->ptr (TC), based on the original value of

          hinfo->_pentry (MSC) or hinfo->ptr (TC), the size of the memory

          block [returned in hinfo->_size (MSC) or hinfo->size (TC)], and

          its status (hinfo->useflag or hinfo->in_use), USEDENTRY or

          FREEENTRY.


          Note that these functions will also "walk" through the virtual

          memory blocks as well.  When a virtual memory block is returned

          as a handle through hinfo->_pentry or hinfo->ptr it must first be

          dereferenced before accessing directly.  For further information

          on virtual memory blocks, see the section entitled "Using the

          virtual memory manager".





                                         37




          MoreHeap                                  Reference Manual  6


          Each call returns:


          _HEAPOK             Good pointer

          _HEAPBADBEGIN       Heap is corrupt

          _HEAPBADPTR         Not a valid heap pointer

          _HEAPBADLINK        A heap entry's header is corrupt

          _HEAPFRAGMENT       Adjacent free block's found

          _HEAPBADCKSUM       A write protected block has been modified

          _HEAPBUFOVWR        Write past the end of a buffer

          _HEAPEND            Returned last block in heap


          Any return values other than _HEAPOK or _HEAPEND indicate some

          sort of overwrite of heap memory.












































                                         38




          MoreHeap                                  Reference Manual  6


          6.2.14.
          6.2.14.
          6.2.14.   malloc, _fmalloc, _hmalloc, farmalloc
                    malloc, _fmalloc, _hmalloc, farmalloc
                    malloc, _fmalloc, _hmalloc, farmalloc


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          void far *malloc ( size_t nbytes )
          void far *malloc ( size_t nbytes )
          void far *malloc ( size_t nbytes )

          void far *_fmalloc ( size_t nbytes )
          void far *_fmalloc ( size_t nbytes )
          void far *_fmalloc ( size_t nbytes )


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void far *_hmalloc ( unsigned long nbytes )
          void far *_hmalloc ( unsigned long nbytes )
          void far *_hmalloc ( unsigned long nbytes )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>


          void far *farmalloc ( unsigned long nbytes )
          void far *farmalloc ( unsigned long nbytes )
          void far *farmalloc ( unsigned long nbytes )

          void far *malloc ( size_t nbytes )
          void far *malloc ( size_t nbytes )
          void far *malloc ( size_t nbytes )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          malloc()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _fmalloc().


          _fmalloc()      Replacement for _fmalloc().


          _hmalloc()      Same as _fmalloc but will take an argument

                          greater than 64K up to 1MB (less 32 bytes.)


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          malloc()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to or farmalloc (TC).


          farmalloc()     Replacement for farmalloc().  Will not allocate

                          blocks larger than 1MB (less 32 bytes.)


          ___________
          Description


          Returns a far pointer to the newly allocated memory block on

          success.  Returns NULL on failure.









                                         39




          MoreHeap                                  Reference Manual  6


          6.2.15.
          6.2.15.
          6.2.15.   mhenable, mhdisable, mhquery
                    mhenable, mhdisable, mhquery
                    mhenable, mhdisable, mhquery


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int mhenable ( int src )
          int mhenable ( int src )
          int mhenable ( int src )

          int mhdisable ( int src )
          int mhdisable ( int src )
          int mhdisable ( int src )

          int mhquery ( int src )
          int mhquery ( int src )
          int mhquery ( int src )


          _____________
          Compatibility


          MSC and TC have no comparable functions.


          ___________
          Description


          mhenable() will "turn on" one of the available heap sources. Call

          mhenable with the "src" parameter set to:


          DOS                      (on by default)

          UMB                      (off by default)

          VID                      (off by default)

          EMM                      (off by default)

          HMA                      (off by default)



          to turn on the respective memory source.


          mhdisable() will "turn off" one of the available heap sources.

          Call mhdisable with the "src" parameter set to the above to turn

          off a memory source.


          Both functions return 1 on success, 0 on failure.  0 is returned

          only if "src" is not one of the above.


          Call mhquery() with the "src" parameter set to one of the above

          to determine whether or not a memory source is enabled.


          mhquery() returns 1 if the source is enabled, 0 if it is not, -1

          if the source is not recognized.

















                                         40




          MoreHeap                                  Reference Manual  6


          6.2.16.
          6.2.16.
          6.2.16.   mhexit
                    mhexit
                    mhexit


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void mhexit ( void )
          void mhexit ( void )
          void mhexit ( void )


          _____________
          Compatibility


          TC and MSC have no comparable function.


          ___________
          Description


          If you have used the virtual memory functions, UMB, VID

          (aggressive), HMA, or EMM, mhexit() must be called before exiting

          your program.  mhexit() will release all extended memory,

          expanded memory, UMBs, the HMA, allocated disk space, and will

          reset the video card if necessary.


          When the heap is initialized mhexit() is registered with the

          atexit() function. Therefore, any program that terminates via

          exit() will perform the necessary cleanup operations.


          A common mistake is to not recognize exec??() as a termination of

          the process. If your program terminates via exec??() you must

          call mhexit() immediately before calling exec??().






























                                         41




          MoreHeap                                  Reference Manual  6


          6.2.17.
          6.2.17.
          6.2.17.   mhheapdump, mhcheapdump, _mhheapdump
                    mhheapdump, mhcheapdump, _mhheapdump
                    mhheapdump, mhcheapdump, _mhheapdump


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int mhheapdump ( void )
          int mhheapdump ( void )
          int mhheapdump ( void )

          int mhcheapdump ( void )
          int mhcheapdump ( void )
          int mhcheapdump ( void )

          int _mhheapdump ( FILE *f )
          int _mhheapdump ( FILE *f )
          int _mhheapdump ( FILE *f )


          _____________
          Compatibility


          MSC and TC have no comparable functions.


          ___________
          Description


          This function will display the contents of the far heap, entry by

          entry, including the pointer value or handle (for virtual memory

          blocks), the memory block status (FREE or USED), number of locks

          (for virtual memory blocks), the source of the memory (DOS, UMB,

          HMA, EMM, VID, or SWAP), and the first 10 bytes of the block in

          ASCII and in hex.


          The function will also check the integrity of the heap by

          returning one of these codes:


          _HEAPOK        Good pointer

          _HEAPBADBEGIN  Heap is corrupt

          _HEAPBADPTR    Not a valid heap pointer

          _HEAPBADLINK   A heap entry's header is corrupt

          _HEAPBADCKSUM  A write protected block has been modified

          _HEAPBUFOVWR   Write past the end of a buffer

          _HEAPFRAGMENT  Adjacent free block's found



          Any return values other than _HEAPOK indicate some sort of

          overwrite of heap memory.


          mhheapdump() writes to stderr.  mhcheapdump() uses the console

          output.  Under TC console output is still usable when using the

          aggressive video ram technique. _mhheapdump() will output to an

          io stream passed as argument.















                                         42




          MoreHeap                                  Reference Manual  6


          6.2.18.
          6.2.18.
          6.2.18.   mhpackheap
                    mhpackheap
                    mhpackheap


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void mhpackheap ( void )
          void mhpackheap ( void )
          void mhpackheap ( void )


          _____________
          Compatibility


          MSC and TC have no comparable function.


          ___________
          Description


          mhpackheap() will swap out all swappable memory pages to extended

          memory or disk, discard all discardable clocks, and release all

          free pages back to DOS.  This function is used primarily to

          provide maximum RAM to a spawned program.







































                                         43




          MoreHeap                                  Reference Manual  6


          6.2.19.
          6.2.19.
          6.2.19.   mhcompactheap
                    mhcompactheap
                    mhcompactheap


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          void mhcompactheap ( void )
          void mhcompactheap ( void )
          void mhcompactheap ( void )


          _____________
          Compatibility


          MSC and TC have no comparable function.


          ___________
          Description


          mhcompactheap() will attempt to reallocate swappable and

          discardable pages lower into ram to create one larger block at

          the top of ram.  This function could be used after a failed

          malloc() or failed vmderef() in an attempt to create additional

          space to swap in a block or create an addressable block.







































                                         44




          MoreHeap                                  Reference Manual  6


          6.2.20.
          6.2.20.
          6.2.20.   _msize, _fmsize, farmsize
                    _msize, _fmsize, farmsize
                    _msize, _fmsize, farmsize


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          unsigned _msize ( void far *p )
          unsigned _msize ( void far *p )
          unsigned _msize ( void far *p )

          unsigned long _fmsize ( void far *p )
          unsigned long _fmsize ( void far *p )
          unsigned long _fmsize ( void far *p )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned _msize ( void far *p )
          unsigned _msize ( void far *p )
          unsigned _msize ( void far *p )

          unsigned long farmsize ( void far *p )
          unsigned long farmsize ( void far *p )
          unsigned long farmsize ( void far *p )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          _msize()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _fmsize().


          _fmsize()       Replacement for MSC's _fmsize().


          _____ _
          Turbo C


          _msize()        Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to TC's farmsize().


          farmsize()      has no comparable function.


          ___________
          Description


          Returns the total allocated size in bytes of the block pointed to

          by "p".  Note that MoreHeap  has a minimum block size of 4 bytes.

          The requested number of bytes, if less than 4, is not retained.

          Therefore, msize() returns the block size after this adjustment,

          not before.


          Also, these functions can return the allocated size of a virtual

          memory handle. Pass the handle to the function, casted to a far

          pointer (NOT vmderefe'd!)










                                         45




          MoreHeap                                  Reference Manual  6


          For example:


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>

          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void *p;
          void *p;
          void *p;

          unsigned s;
          unsigned s;
          unsigned s;


          int main ()
          int main ()
          int main ()

          {
          {
          {

               p = malloc ( 1 );
               p = malloc ( 1 );
               p = malloc ( 1 );

               printf ( "p = %u bytes\n", msize ( p ) );
               printf ( "p = %u bytes\n", msize ( p ) );
               printf ( "p = %u bytes\n", msize ( p ) );

          }
          }
          }


          In this case the program will output:


          p = 4 bytes
          p = 4 bytes
          p = 4 bytes


          instead of


          p = 1 bytes
          p = 1 bytes
          p = 1 bytes


          as you might expect.


































                                         46




          MoreHeap                                  Reference Manual  6


          6.2.21.
          6.2.21.
          6.2.21.   realloc, _frealloc, _hrealloc, farrealloc
                    realloc, _frealloc, _hrealloc, farrealloc
                    realloc, _frealloc, _hrealloc, farrealloc


          _____
          Usage


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>


          void far *realloc ( size_t nbytes )
          void far *realloc ( size_t nbytes )
          void far *realloc ( size_t nbytes )

          void far *_frealloc ( size_t nbytes )
          void far *_frealloc ( size_t nbytes )
          void far *_frealloc ( size_t nbytes )

          void far *_hrealloc ( unsigned long nbytes )
          void far *_hrealloc ( unsigned long nbytes )
          void far *_hrealloc ( unsigned long nbytes )


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          #include <alloc.h>
          #include <alloc.h>
          #include <alloc.h>


          void far *realloc ( size_t nbytes )
          void far *realloc ( size_t nbytes )
          void far *realloc ( size_t nbytes )

          void far *farrealloc ( unsigned long nbytes )
          void far *farrealloc ( unsigned long nbytes )
          void far *farrealloc ( unsigned long nbytes )


          _____________
          Compatibility


          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C
          _________ ___ _____ _
          Microsoft and Aztec C


          realloc()       Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to _frealloc().


          _frealloc()     for MSC's _frealloc.


          _hrealloc()     Same as _frealloc but will take an argument

                          greater than 64K up to 1MB (less 32 bytes.)


          _____ _
          Turbo C
          _____ _
          Turbo C
          _____ _
          Turbo C


          realloc()       Under small model uses the original RTL

                          functions.  Under large model passes the call

                          through to farrealloc().


          farrealloc()    Replacement for TC's farrealloc().  Will only

                          allocate a block up to 1MB (less 32 bytes.)


          ___________
          Description


          Returns a far pointer to the reallocated memory block on success.

          Returns NULL on failure.












                                         47




          MoreHeap                                  Reference Manual  6


          6.2.22.
          6.2.22.
          6.2.22.   VID_init, VID_safe, VID_reserve
                    VID_init, VID_safe, VID_reserve
                    VID_init, VID_safe, VID_reserve


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          int VID_init ( void )
          int VID_init ( void )
          int VID_init ( void )

          unsigned VID_safe
          unsigned VID_safe
          unsigned VID_safe

          unsigned VID_reserve
          unsigned VID_reserve
          unsigned VID_reserve


          _____________
          Compatibility


          No comparable functions exist in either TC or MSC.


          ___________
          Description


          These functions are only relevant if you have an EGA/VGA card

          with 128K of RAM or more.


          If VID_safe is equal to 1 (the default), the less aggressive

          video ram method is used,  This technique can provide an

          additional 28K of heap space.


          If VID_safe is equal to 0, the more aggressive technique is used,

          adding up to 60K of additional heap space.


          When VID_safe is equal to 0, VID_init() will reset the video card

          mode by directly programming the EGA/VGA card into a nonstandard

          16 page, 80 X 25 character mode.  This mode will use 0xA0000000

          as its base address, instead of 0xB8000000.  Once the base

          address has changed, the bios and dos output routines will not

          work. This means putc, printf, puts, gets, etc. will not operate.


          In order to make this mode work for you-- If you are doing screen

          output via direct reads and writes to video ram you will need to

          modify it to use 0xA0000000 as the base address.  If you are

          using TCs console output (cprintf, cputs, etc.) MoreHeap will

          automatically update their dependent data structures with

          0xA0000000 as the video ram address.


          MoreHeap will begin allocating video ram to the heap at the

          location 0xA0000000 (aggressive) or 0xB8000000 (safe) plus

          VID_reserve bytes.  VID_reserve is by default set to 16K.  This

          setting allows you to use up to four video pages in the 80 X 25

          character mode.  If you only want to use 1 page, set VID_reserve

          to 4K.  If you want to use three pages set it equal to 12K. At

          16K this seems to work with most debuggers.


          In addition, if you are using the aggressive mode you should call

          VID_init() at the beginning of your program to avoid any changes

          in video mode midway through your application.







                                         48




          MoreHeap                                  Reference Manual  6



          6.3.
          6.3.
          6.3. Using debugging features
               Using debugging features
               Using debugging features


          MoreHeap has two basic debugging modes, TRACE and DEBUG. TRACE

          continuously writes filename and line number for every heap

          transaction made within a file compiled with  _HEAPTRACE defined.

          Debug mode is similar but will only print this information out

          when it finds that the heap has been corrupted.


          At any time you may print a list of all of the nodes within the

          heap, a heap dump. If you use the _HEAPLOG feature in conjunction

          with _HEAPTRACE or _HEAPDEBUG the heap dump will also include the

          filename and line number where each block was allocated or freed.


          You can improve MoreHeap's ability to detect heap corruption by

          using the heappad feature. The heappad feature will pad each

          allocation with X number of bytes, and put a special value in

          each byte.  In _HEAPTRACE or _HEAPDEBUG modes these pad bytes

          will be examined for this special value.  If the bytes have been

          modified the program will terminate, providing the filename and

          line number of the last heap transaction. This error indicates

          you have probably overwritten an allocated block.


          If a heap block is being modified, but within its allocated

          space, none of the techniques discussed so far will work.  In

          this situation you can write protect blocks which should not be

          modified. When a block is write protected a checksum byte is

          added to the allocated block.  In _HEAPDEBUG and _HEAPTRACE modes

          this checksum byte is recomputed on each heap transaction and

          compared to the original checksum. If the values are different an

          error is reported.


          If you wish to perform heap integrity checks in a more focused

          manner than _HEAPDEBUG or _HEAPTRACE you can simply call

          farheapcheck() or _fheapchk() at anytime within your program.

          This function will check the internal consistency, the heappad,

          and the checksums and report on problems via its return value.




















                                         49




          MoreHeap                                  Reference Manual  6


          6.3.1.
          6.3.1.
          6.3.1.    _HEAPDEBUG
                    _HEAPDEBUG
                    _HEAPDEBUG


          If you define this constant to the name of an io stream (stderr,

          for example) and recompile all source modules which call free(),

          malloc(), calloc(), realloc(), or expand(), each call to these

          functions will be redefined to debug versions of the same

          functions, for example, malloc() will be redefined to

          malloc_dbg().  These debug versions will call the original

          function and then call heapcheck().  If heapcheck() indicates any

          heap corruption the program will output the heap error message,

          and the line number and source module where the heap function was

          called.  You can narrow down any bugs to code that executed

          between the previous heap function call and the heap function

          call that indicated the error.


          If you find it difficult to determine what the previous heap

          function call was you may want to use _HEAPTRACE.  _HEAPTRACE is

          defined in the next section.


          To compile a module with heap debugging enabled under Microsoft

          C, #include the MoreHeap header file <heap.h> and type the

          following at the following command line:


          CL /D_HEAPDEBUG=stderr DEMO.C
          CL /D_HEAPDEBUG=stderr DEMO.C
          CL /D_HEAPDEBUG=stderr DEMO.C


          Alternatively, you could include the following lines in the

          modules where you want heap debugging enabled:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #define _HEAPDEBUG
          #define _HEAPDEBUG
          #define _HEAPDEBUG       stderr
                                   stderr
                                   stderr


          To direct the heap debug output to a file you could do something

          like this:


          #include <stdio.h>
          #include <stdio.h>
          #include <stdio.h>

          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #define _HEAPDEBUG
          #define _HEAPDEBUG
          #define _HEAPDEBUG       heapdmp
                                   heapdmp
                                   heapdmp


          FILE *heapdmp;
          FILE *heapdmp;
          FILE *heapdmp;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               heapdmp = fopen ("heap.dmp","w" );
               heapdmp = fopen ("heap.dmp","w" );
               heapdmp = fopen ("heap.dmp","w" );

               .
               .
               .

               .
               .
               .

               .
               .
               .

          }
          }
          }










                                         50




          MoreHeap                                  Reference Manual  6


          6.3.2.
          6.3.2.
          6.3.2.    _HEAPTRACE
                    _HEAPTRACE
                    _HEAPTRACE


          If you define this constant to the name of an io stream (stderr,

          for example) and recompile all source modules which call free(),

          malloc(), calloc(), realloc(), or expand(), each call to these

          functions will be redefined to the trace versions of the same

          functions, for example, malloc_trace.  These trace versions will

          call the original function and then call heapcheck().  And then

          print the heap status, and the line number and source module

          where the heap function was called.  If any heap errors are

          detected you can narrow down any bugs to code that executed

          between the previous heap function call and the heap function

          call that indicated the error.


          To compile a module with heap tracing enabled under Microsoft C,

          #include the MoreHeap header file <heap.h> and type the following

          at the following command line:


          CL /D_HEAPTRACE=stderr DEMO.C
          CL /D_HEAPTRACE=stderr DEMO.C
          CL /D_HEAPTRACE=stderr DEMO.C


          Alternatively, you could include the following lines in the

          modules where you want heap tracing enabled:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #define _HEAPTRACE
          #define _HEAPTRACE
          #define _HEAPTRACE       stderr
                                   stderr
                                   stderr


          To direct the heap trace output to a file you could do something

          like this:


          #include <stdio.h>
          #include <stdio.h>
          #include <stdio.h>

          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #define _HEAPTRACE
          #define _HEAPTRACE
          #define _HEAPTRACE       heapdmp
                                   heapdmp
                                   heapdmp


          FILE *heapdmp;
          FILE *heapdmp;
          FILE *heapdmp;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               heapdmp = fopen ("heap.dmp","w" );
               heapdmp = fopen ("heap.dmp","w" );
               heapdmp = fopen ("heap.dmp","w" );

               .
               .
               .

               .
               .
               .

               .
               .
               .

          }
          }
          }















                                         51




          MoreHeap                                  Reference Manual  6


          6.3.3.
          6.3.3.
          6.3.3.    _HEAPLOG
                    _HEAPLOG
                    _HEAPLOG


          You can optionally record the filename and line number where each

          block was allocated and freed when using the _HEAPTRACE and

          _HEAPDEBUG modes by defining _HEAPLOG. For example to compile a

          module with the _HEAPLOG and _HEAPTRACE features under MS C:


          cl /_DHEAPTRACE=stdout /D_HEAPLOG test1.c
          cl /_DHEAPTRACE=stdout /D_HEAPLOG test1.c
          cl /_DHEAPTRACE=stdout /D_HEAPLOG test1.c



          This will add 4-6 bytes to each block allocated.


          the heapdump routines will print the filename and line number

          where each block was allocated or freed when using this feature.











































                                         52




          MoreHeap                                  Reference Manual  6


          6.3.4.
          6.3.4.
          6.3.4.    mh_heappad, mh_padchar
                    mh_heappad, mh_padchar
                    mh_heappad, mh_padchar


          If you write past the end of an allocated block you may be

          destroying the next memory block's header. This can completely

          corrupt the heap and is often a very difficult bug to find. This

          can sometimes manifest itself when switching from Turbo C, which

          allocates on paragraph boundaries, and Microsoft C (or MoreHeap)

          which allocates on byte boundaries. A buffer overwrite under

          Turbo C could just be hidden in its "padding".


          If you think this is the case globally define mh_heappad to a

          value between 1 and 255 like this:


          unsigned char mh_heappad = 4;
          unsigned char mh_heappad = 4;
          unsigned char mh_heappad = 4;



          This will establish a padding of mh_heappad bytes at the end of

          every allocated block. These pad bytes will be filled with the

          value of mh_padchar (0xFF by default.) Every call to

          farheapcheck()/_fheapchk() will test the value of the pad bytes.

          If a buffer overwrite is detected a value of _HEAPBUFOVWR will be

          returned.


          Example:


          #include <malloc.h>
          #include <malloc.h>
          #include <malloc.h>

          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          unsigned char mh_heappad = 4;
          unsigned char mh_heappad = 4;
          unsigned char mh_heappad = 4;


          int main ( )
          int main ( )
          int main ( )

          {
          {
          {

               char *x;
               char *x;
               char *x;

               x = malloc ( 10 );
               x = malloc ( 10 );
               x = malloc ( 10 );

               mhheapdump();
               mhheapdump();
               mhheapdump();

               strcpy ( x, "1234567890" );
               strcpy ( x, "1234567890" );
               strcpy ( x, "1234567890" );

               mhheapdump();
               mhheapdump();
               mhheapdump();

          }
          }
          }



















                                         53




          MoreHeap                                  Reference Manual  7



          7.
          7.
          7.   Using the virtual memory manager
               Using the virtual memory manager
               Using the virtual memory manager


          MoreHeap provides routines that allow your programs to use

          expanded memoryu, extended memory, disk, and conventional memory.

          As memory becomes full MoreHeap will begin to "swap" data back

          and forth to expanded memory, extended memory, and then to disk.

          This technique can provide you with as much as 128 megabytes of

          additional heap space.  This space is made available to your

          system through calls to the function vmmalloc(), which is similar

          to malloc() in C.


          (A single allocated memory block must be small enough to be

          swapped into addressable memory.  This means that although your

          total allocated space can be 128 megabytes there is a practical

          limit of 400-500K on block size.)









































                                         54




          MoreHeap                                  Reference Manual  7



          7.1.
          7.1.
          7.1. Dereferencing Handles
               Dereferencing Handles
               Dereferencing Handles























































                                         55




          MoreHeap                                  Reference Manual  7


          ______
          7.1.1.
          ______
          7.1.1.
          ______
          7.1.1.    
                    
                    
                    
                    
                    ___ ____________
                    Why dereference?
                    ___ ____________
                    Why dereference?
                    ___ ____________
                    Why dereference?


          Because of the swapping inherent in the use of the virtual memory

          manager, a particular block of memory you would like to access

          may not be in memory at any given time.  To mitigate this

          problem, the virtual memory allocation functions are designed to

          return "handles", not pointers.  Unlike pointers, you cannot

          directly address handles.  You must first dereference the handle

          to obtain a pointer and then you can manipulate the memory block

          through this pointer.  The process of dereferencing is the

          foundation of the virtual memory manager.  Dereferencing allows

          the virtual memory manager to:


               .    relocate memory blocks


               .    determine that a desired memory block is in addressable

                    memory.








































                                         56




          MoreHeap                                  Reference Manual  7


          ______
          7.1.2.
          ______
          7.1.2.
          ______
          7.1.2.    
                    
                    
                    
                    
                    ___ __ ___________
                    How to dereference
                    ___ __ ___________
                    How to dereference
                    ___ __ ___________
                    How to dereference


          Handles can be dereferenced with a call to vmderef().  vmderef()

          is called with a handle provided by a previous call to

          vmmalloc().  vmderef() returns a pointer to addressable memory.

          Only after dereferencing the pointer can you access it directly.

          The pointer will remain valid only until another call has been

          made to another heap function.  Other heap functions can cause

          more "swapping" to take place which may invalidate the pointer.


          Swapping does not take place exclusively as a result of a call to

          a virtual memory manager function.  ANY heap function, can

          initiate a swap. The cooperative nature of the heap manager

          allows you to use a mixture of directly addressable heap and

          virtual heap.  As your needs for directly addressable heap

          increase, virtual heap space will simply begin to swap itself to

          extended memory or disk.


          An often overlooked problem is that certain RTL functions call

          malloc(). For example, many implementations of printf() call

          malloc(). Therefore, printf() can invalidate a dereferenced

          pointer.



































                                         57




          MoreHeap                                  Reference Manual  7


          ______
          7.1.3.
          ______
          7.1.3.
          ______
          7.1.3.    
                    
                    
                    
                    
                    ____ _____ ________
                    More about swapping
                    ____ _____ ________
                    More about swapping
                    ____ _____ ________
                    More about swapping


          Swapping is done on a "page" basis.  Every handle belongs to a

          page.  Usually several handles will belong to one page.  When a

          handle is dereferenced space is allocated in addressable memory

          and the handle's entire page is copied from extended memory or

          disk into addressable memory.  Once this takes place a valid

          pointer can be constructed based on the new address of the page

          and be returned as the dereferenced value of the handle.


          Whenever a request is made to dereference a handle and there is

          not enough room in addressable memory for its page, the virtual

          memory manager will begin to copy pages back out to extended

          memory or disk and free the memory they were occupying.  This

          process repeats until enough addressable memory can be found to

          dereference the requested page.









































                                         58




          MoreHeap                                  Reference Manual  7



          7.2.
          7.2.
          7.2. Locking Blocks
               Locking Blocks
               Locking Blocks


          If a handle is frequently referred to you may want to "lock" it.

          Once a handle is locked, additional calls to the heap management

          functions cannot invalidate the handle by swapping its page back

          to extended memory or disk.  Judicious use of locking can improve

          both performance and code size by reducing the number of calls to

          vmderef().


          When a handle is locked, its page is marked as locked.  A locked

          page cannot be swapped out of addressable memory.  If too many

          pages are locked subsequent dereferences may fail due to lack of

          swappable space in addressable memory.


          When a locked handle is freed its page is also unlocked.  You can

          also unlock a handle without freeing it by calling vmunlk().








































                                         59




          MoreHeap                                  Reference Manual  7



          7.3.
          7.3.
          7.3. Freeing Blocks
               Freeing Blocks
               Freeing Blocks


          To release handles back to the free pool of handles call

          vmfree().  Also frees any related extended memory, DOS memory,

          and disk space.



















































                                         60




          MoreHeap                                  Reference Manual  7



          7.4.
          7.4.
          7.4. Freeing Expanded Memory, Extended Memory & Disk space
               Freeing Expanded Memory, Extended Memory & Disk space
               Freeing Expanded Memory, Extended Memory & Disk space


          Before exiting your program you should call mhexit().  This

          function will release any expanded memory, extended memory,  and

          disk space utilized by the virtual memory manager.  If you are

          using the aggressive video ram technique this function will also

          reset the video card.


          mhexit() is registered via atexit() when the heap is initialized.

          If your program exits by exit() you do not need to explicitly

          call mhexit().













































                                         61




          MoreHeap                                  Reference Manual  7



          7.5.
          7.5.
          7.5. Using HIMEM.SYS
               Using HIMEM.SYS
               Using HIMEM.SYS


          The virtual memory manager allocates memory blocks out of

          extended memory using HIMEM.SYS.  Each memory block allocated out

          of extended memory is a minimum of _amblksiz bytes.  By default

          HIMEM.SYS will allocate just 32 memory blocks and _amblksiz is

          8192 bytes.)  This means that using the default settings you can

          only allocate 256K of space out of extended memory.  To increase

          the maximum allocatable space out of extended memory you can:


               .    Use the /NUMHANDLES=n parameter when invoking

                    HIMEM.SYS.  Each additional handle requires 6 bytes of

                    memory and the maximum number of handles is 128.  (This

                    will cost you 576 bytes of addressable memory to go

                    from the default to the maximum value.)


               .    Increase the size of _amblksiz.  Anything larger than

                    64K does not seem to improve performance.


          If you use the maximum values for both parameters you can

          allocate up to 128 pages of 64K bytes or 8192K of space.



































                                         62




          MoreHeap                                  Reference Manual  7



          7.6.
          7.6.
          7.6. Functions & Globals
               Functions & Globals
               Functions & Globals























































                                         63




          MoreHeap                                  Reference Manual  7


          7.6.1.
          7.6.1.
          7.6.1.    _swp_size
                    _swp_size
                    _swp_size


          Determines the maximum number of entries in the swap table.  The

          swap table keeps track of all swappable pages.  A swappable page

          is a multiple of _amblksiz.  So, if _amblksiz were equal to 16K

          and _swp_size were set to 100 the maximum amount of virtual

          memory the swap table could reference would be 16K * 100 (or

          1.6MB.)


          The initial swap table size is set at 128 and the initial

          _amblksiz is set at 8K, allowing a minimum of 1MB of virtual

          memory.


          You can change _swp_size by declaring _swp_size globally and

          assigning it a value like this:


          unsigned _swp_size = 256;


          Each swap table entry requires 32 bytes. Therefore, _swp_size *

          32 would represent the total bytes allocated to the swap table.

          For example, a 256-entry swap table would require 8K of RAM.




































                                         64




          MoreHeap                                  Reference Manual  7


          7.6.2.
          7.6.2.
          7.6.2.    SWAPPATH
                    SWAPPATH
                    SWAPPATH


          The swap filename and location can be altered by creating an

          environment variable named SWAPPATH. This variable should contain

          a standard DOS filename that finishes with six X's. The six X's

          represent the portion of the name that is used by operating

          system to fill in a unique set of characters which does not

          conflict with any existing filenames.


          For example:


          SET SWAPPATH=C:\APPXXXXXX
          SET SWAPPATH=C:\APPXXXXXX
          SET SWAPPATH=C:\APPXXXXXX


          would put the swap file in the root of the C drive with a name

          that began with APP.










































                                         65




          MoreHeap                                  Reference Manual  7


          7.6.3.
          7.6.3.
          7.6.3.    _swp_safety
                    _swp_safety
                    _swp_safety


          _____
          Usage


          #include <disk.h>
          #include <disk.h>
          #include <disk.h>


          long _swp_safety
          long _swp_safety
          long _swp_safety


          ___________
          Description


          When allocating virtual memory blocks and swapping to disk, if

          you ran out of disk space it would be possible to create a

          scenario where while attempting to swap IN blocks int addressable

          memory it was first necessary to swap OUT blocks to disk-but that

          there would be no available swap OUT space. A virtual memory

          catch-22.


          As a solution, the disk swap file has a 'safety zone' If this

          safety zone is used to satisfy a swap OUT, mherr() returns a

          DSKWARN error. This error means that you are seriously low on

          disk space and should consider shutting down the system. You can

          modify the safety zone size at anytime by modifying the value of

          _swp_safety (default 0xFFFFL.)


          Do not panic if mherr() returns a DSKERR message. This simply

          means that at least ONE block could not be swapped out for lack

          of disk space. As long as vmderef() returns a non-NULL value the

          swap was successfully completed. DSKERR is just another level of

          concern above DSKWARN.




























                                         66




          MoreHeap                                  Reference Manual  7


          7.6.4.
          7.6.4.
          7.6.4.    _use_LRU
                    _use_LRU
                    _use_LRU


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          int _use_LRU
          int _use_LRU
          int _use_LRU


          ___________
          Description


          The virtual memory manager uses a Least Recently Used (LRU)

          algorithm. To turn off LRU set _use_LRU to 0.













































                                         67




          MoreHeap                                  Reference Manual  7


          7.6.5.
          7.6.5.
          7.6.5.    _swp_msg
                    _swp_msg
                    _swp_msg


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void ( *_swp_msg ) ( int t )
          void ( *_swp_msg ) ( int t )
          void ( *_swp_msg ) ( int t )



          ___________
          Description


          The _swp_msg variable is a pointer to a function that can be

          called whenever a virtual memory block is going to be swapped

          out. You set the variable to point to a function that displays a

          message to the user like "Swapping..." to indicate that there

          might be a slight delay.









































                                         68




          MoreHeap                                  Reference Manual  7


          7.6.6.
          7.6.6.
          7.6.6.    vmderef
                    vmderef
                    vmderef


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void far * vmderef( MHNDL ptr, unsigned lock )
          void far * vmderef( MHNDL ptr, unsigned lock )
          void far * vmderef( MHNDL ptr, unsigned lock )


          ___________
          Description


          Swaps the page, to which ptr belongs, to addressable memory,

          calculates an addressable pointer to ptr and returns the

          addressable pointer.  This pointer is only valid until another

          call to ANY heap management function.  ANY call to a heap

          management function can initiate a page swap, invalidating the

          pointer.


          If "lock" is equal to defined constant "LOCK" the memory block

          and page will be first dereferenced and then locked.  A locked

          page cannot be invalidated (i.e. swapped out) by subsequent calls

          to the heap manager.  Locking, however, should be used prudently.

          Locks will reduce addressable space and may make subsequent

          dereferences fail (for lack of addressable space to swap a page

          into.)  To not lock the memory block, call vmderef() with "lock"

          set to NO_LOCK.  Use vmunlk() to unlock the memory block.


          vmderef() returns NULL if it cannot swap the page into

          addressable memory.





























                                         69




          MoreHeap                                  Reference Manual  7


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;

               rctngl *r;
               rctngl *r;
               rctngl *r;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = vmcalloc ( 100, sizeof ( rctngl ) );
               p = vmcalloc ( 100, sizeof ( rctngl ) );
               p = vmcalloc ( 100, sizeof ( rctngl ) );


               /* dereference virtual memory handle */
               /* dereference virtual memory handle */
               /* dereference virtual memory handle */

               r = vmderef ( p, NO_LOCK );
               r = vmderef ( p, NO_LOCK );
               r = vmderef ( p, NO_LOCK );


               /* Use derefed pointer */
               /* Use derefed pointer */
               /* Use derefed pointer */

               r[0].x1 = r[0].y1 = 1;
               r[0].x1 = r[0].y1 = 1;
               r[0].x1 = r[0].y1 = 1;

               r[0].x2 = r[0].y2 = 10;
               r[0].x2 = r[0].y2 = 10;
               r[0].x2 = r[0].y2 = 10;

               .
               .
               .

               .
               .
               .

               .
               .
               .

               mhexit();
               mhexit();
               mhexit();

          }
          }
          }






























                                         70




          MoreHeap                                  Reference Manual  7


          7.6.7.
          7.6.7.
          7.6.7.    vmfree
                    vmfree
                    vmfree


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void vmfree ( MHNDL ptr )
          void vmfree ( MHNDL ptr )
          void vmfree ( MHNDL ptr )


          ___________
          Description


          Returns "ptr" to the free pool of handles.  Performs a quick,

          minimum internal consistency check to determine if the block is

          truly "used" before freeing it.  If block is "locked", block is

          first "unlocked" before freeing it.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;

               rctngl *r;
               rctngl *r;
               rctngl *r;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = vmcalloc ( 100, sizeof ( rctngl ) );
               p = vmcalloc ( 100, sizeof ( rctngl ) );
               p = vmcalloc ( 100, sizeof ( rctngl ) );

               mhheapdump();
               mhheapdump();
               mhheapdump();


               /* free virtual memory handle */
               /* free virtual memory handle */
               /* free virtual memory handle */

               vmfree ( p );
               vmfree ( p );
               vmfree ( p );

               mhheapdump();
               mhheapdump();
               mhheapdump();

               mhexit();
               mhexit();
               mhexit();

          }
          }
          }




















                                         71




          MoreHeap                                  Reference Manual  7


          7.6.8.
          7.6.8.
          7.6.8.    vmmalloc
                    vmmalloc
                    vmmalloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL vmmalloc ( unsigned long nbytes )
          MHNDL vmmalloc ( unsigned long nbytes )
          MHNDL vmmalloc ( unsigned long nbytes )


          ___________
          Description


          Returns a handle to the newly allocated memory block on success.

          Returns NULL on failure.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               mhexit();
               mhexit();
               mhexit();


          }
          }
          }
























                                         72




          MoreHeap                                  Reference Manual  7


          7.6.9.
          7.6.9.
          7.6.9.    vmrealloc
                    vmrealloc
                    vmrealloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL vmrealloc ( MHNDL ptr, unsigned long nbytes )
          MHNDL vmrealloc ( MHNDL ptr, unsigned long nbytes )
          MHNDL vmrealloc ( MHNDL ptr, unsigned long nbytes )


          ___________
          Description


          Resizes the memory block pointed to by "ptr" to "nbytes" bytes.

          On success returns a handle to the newly allocated block.  The

          contents of the original memory block are copied to the new

          memory block.  vmrealloc() will first attempt to expand the

          original memory block and avoid the subsequent copy and free of

          the old block if possible, in order to improve performance.


          On failure returns a NULL.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               /* reallocate to an array of 200 "rctngls" */
               /* reallocate to an array of 200 "rctngls" */
               /* reallocate to an array of 200 "rctngls" */

               p = vmrealloc ( p, 200 * sizeof ( rctngl ) );
               p = vmrealloc ( p, 200 * sizeof ( rctngl ) );
               p = vmrealloc ( p, 200 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );

               mhexit();
               mhexit();
               mhexit();

          }
          }
          }
















                                         73




          MoreHeap                                  Reference Manual  7


          7.6.10.
          7.6.10.
          7.6.10.   vmunlk
                    vmunlk
                    vmunlk


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          void vmunlk ( MHNDL ptr )
          void vmunlk ( MHNDL ptr )
          void vmunlk ( MHNDL ptr )


          ___________
          Description


          Removes 1 lock on a memory block (provided the memory block was

          locked.)  In order to "unlock" a memory block you must call

          vmunlk() once for every call to vmderef() with the "lock"

          parameter set to LOCK.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );
               p = vmmalloc ( 100 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );

               vmderef ( p, LOCK );
               vmderef ( p, LOCK );
               vmderef ( p, LOCK );

               printf("With lock ON\n\n");
               printf("With lock ON\n\n");
               printf("With lock ON\n\n");

               mhheapdump();
               mhheapdump();
               mhheapdump();

               vmunlk( p );
               vmunlk( p );
               vmunlk( p );

               printf("With lock OFF\n\n");
               printf("With lock OFF\n\n");
               printf("With lock OFF\n\n");

               mhheapdump();
               mhheapdump();
               mhheapdump();

               mhexit();
               mhexit();
               mhexit();

          }
          }
          }


















                                         74




          MoreHeap                                  Reference Manual  7


          7.6.11.
          7.6.11.
          7.6.11.   dmmalloc
                    dmmalloc
                    dmmalloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL dmmalloc ( unsigned long nbytes )
          MHNDL dmmalloc ( unsigned long nbytes )
          MHNDL dmmalloc ( unsigned long nbytes )


          ___________
          Description


          Returns a handle to the newly allocated discardable memory block

          on success.  Returns NULL on failure.  A discardable memory block

          is never swapped to disk or extended memory.  When additional

          addressable memory is required, in lieu of swapping, the memory

          block is shrunk down to its header size.  Once the memory block

          has been discarded the first subsequent call to vmderef() will

          return NULL, then the memory block header will be deallocated and

          the handle will become invalid.  The handle is now invalid and

          should no longer be used.  Discardable memory blocks are

          generally used for data which is not modified and can be easily

          reread from an existing file, for example code from a .COM file

          or a bitmap from a PCX file.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate a discardable array of 100 "rctngls" */
               /* allocate a discardable array of 100 "rctngls" */
               /* allocate a discardable array of 100 "rctngls" */

               p = dmmalloc ( 100 * sizeof ( rctngl ) );
               p = dmmalloc ( 100 * sizeof ( rctngl ) );
               p = dmmalloc ( 100 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               mhexit();
               mhexit();
               mhexit();

          }
          }
          }















                                         75




          MoreHeap                                  Reference Manual  7


          7.6.12.
          7.6.12.
          7.6.12.   dmcalloc
                    dmcalloc
                    dmcalloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL vmcalloc ( unsigned long nunits, unsigned long unitsz )
          MHNDL vmcalloc ( unsigned long nunits, unsigned long unitsz )
          MHNDL vmcalloc ( unsigned long nunits, unsigned long unitsz )


          ___________
          Description


          Returns a handle to a newly allocated discardable memory block of

          size nunits * unitsz on success.  Returns NULL on failure.  The

          memory block space will be initialized to 0x00.  A discardable

          memory block is never swapped to disk or extended memory.  When

          additional addressable memory is required, in lieu of swapping,

          the memory block is shrunk down to its header size.  Once the

          memory block has been discarded the first subsequent call to

          vmderef() will return NULL, then the memory block header will be

          deallocated and the handle becomes invalid.  The handle is now

          invalid and should no longer be used.  Discardable memory blocks

          are generally used for data which is not modified and can be

          easily reread from an existing file, for example code from a .COM

          file or bitmaps from a PCX file.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = dmcalloc ( 100, sizeof ( rctngl ) );
               p = dmcalloc ( 100, sizeof ( rctngl ) );
               p = dmcalloc ( 100, sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               mhexit();
               mhexit();
               mhexit();

          }
          }
          }














                                         76




          MoreHeap                                  Reference Manual  7


          7.6.13.
          7.6.13.
          7.6.13.   rmmalloc
                    rmmalloc
                    rmmalloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL rmmalloc ( unsigned long nbytes )
          MHNDL rmmalloc ( unsigned long nbytes )
          MHNDL rmmalloc ( unsigned long nbytes )


          ___________
          Description


          Returns a handle to the newly allocated relocatable memory block

          on success.  Returns NULL on failure.  A relocatable memory block

          is never swapped to disk or extended memory.  These memory blocks

          can be relocated lower in memory by a mhcompactheap() call.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate a relocatable array of 100 "rctngls" */
               /* allocate a relocatable array of 100 "rctngls" */
               /* allocate a relocatable array of 100 "rctngls" */

               p = rmmalloc ( 100 * sizeof ( rctngl ) );
               p = rmmalloc ( 100 * sizeof ( rctngl ) );
               p = rmmalloc ( 100 * sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               mhexit();
               mhexit();
               mhexit();

          }
          }
          }























                                         77




          MoreHeap                                  Reference Manual  7


          7.6.14.
          7.6.14.
          7.6.14.   rmcalloc
                    rmcalloc
                    rmcalloc


          _____
          Usage


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>


          MHNDL rmcalloc ( unsigned long nunits, unsigned long unitsz )
          MHNDL rmcalloc ( unsigned long nunits, unsigned long unitsz )
          MHNDL rmcalloc ( unsigned long nunits, unsigned long unitsz )


          ___________
          Description


          Returns a handle to a newly allocated relocatable memory block of

          size nunits * unitsz on success.  Returns NULL on failure.  The

          memory block space will be initialized to 0x00.  A relocatable

          memory block is never swapped to disk or extended memory.  These

          memory blocks can be relocated lower in memory by a

          mhcompactheap() call.


          Example:


          #include <heap.h>
          #include <heap.h>
          #include <heap.h>

          #include <stdlib.h>
          #include <stdlib.h>
          #include <stdlib.h>


          typedef struct {
          typedef struct {
          typedef struct {

               int x1, y1, x2, y2;
               int x1, y1, x2, y2;
               int x1, y1, x2, y2;

          } rctngl;
          } rctngl;
          } rctngl;


          int main ( void )
          int main ( void )
          int main ( void )

          {
          {
          {

               MHNDL p;
               MHNDL p;
               MHNDL p;


               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */
               /* allocate an array of 100 "rctngls" */

               p = rmcalloc ( 100, sizeof ( rctngl ) );
               p = rmcalloc ( 100, sizeof ( rctngl ) );
               p = rmcalloc ( 100, sizeof ( rctngl ) );

               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );
               printf ( "sizeof p is %ld\n",_fmsize ( p ) );


               mhexit();
               mhexit();
               mhexit();

          }
          }
          }





















                                         78




          MoreHeap                                  Reference Manual  8



          8.
          8.
          8.   Buffer Manipulation
               Buffer Manipulation
               Buffer Manipulation


          Virtual memory versions of the standard buffer and string

          manipulation functions are available. These functions operate

          directly on the swap space and therefore do not initiate

          swapping. In some cases it may be more efficient to NOT swap in

          the respective memory blocks and use the functions listed below.


          #include <vmstring.h>
          #include <vmstring.h>
          #include <vmstring.h>


          void far * vmmemset( void far *d, int c, unsigned long n);
          void far * vmmemset( void far *d, int c, unsigned long n);
          void far * vmmemset( void far *d, int c, unsigned long n);

          void far * vmmemmove( void far *d, void far *s, unsigned long n);
          void far * vmmemmove( void far *d, void far *s, unsigned long n);
          void far * vmmemmove( void far *d, void far *s, unsigned long n);

          void far * vmmemcpy( void far *d, void far *s, unsigned long n);
          void far * vmmemcpy( void far *d, void far *s, unsigned long n);
          void far * vmmemcpy( void far *d, void far *s, unsigned long n);

          void far * vmstrlen( char far *s );
          void far * vmstrlen( char far *s );
          void far * vmstrlen( char far *s );

          void far * vmstrdup ( char far *s );
          void far * vmstrdup ( char far *s );
          void far * vmstrdup ( char far *s );

          void far * vmstrcpy ( char far *d, char far *s );
          void far * vmstrcpy ( char far *d, char far *s );
          void far * vmstrcpy ( char far *d, char far *s );

          void far * vmstrncpy ( char far *d, char far *s, unsigned n );
          void far * vmstrncpy ( char far *d, char far *s, unsigned n );
          void far * vmstrncpy ( char far *d, char far *s, unsigned n );

          void far * vmstrcat ( char far *d, char far *s );
          void far * vmstrcat ( char far *d, char far *s );
          void far * vmstrcat ( char far *d, char far *s );

          void far * vmstrncat ( char far *d, char far *s, unsigned n );
          void far * vmstrncat ( char far *d, char far *s, unsigned n );
          void far * vmstrncat ( char far *d, char far *s, unsigned n );


          These function work similar to the standard RTL functions. These

          function will only operate on allocated blocks as both source and

          destination. If you want to transfer between a static buffer and

          a virtual memory block these functions will not work. These

          functions will work on both virtual memory blocks and addressable

          memory blocks (obtained from malloc() etc.) To use these

          functions with virtual memory blocks you must first cast the

          handle to a pointer.




























                                         79




          MoreHeap                                  Reference Manual  9



          9.
          9.
          9.   Error handling, mherr()
               Error handling, mherr()
               Error handling, mherr()


          Many functions return handles or addressable pointers as the

          result of their operation.  These functions generally return NULL

          if they were unable to perform the operation.  In order to

          determine why the operation was not performed you must call

          mherr().  mherr() will return one of these values indicating why

          the operation was not performed:


          NOMEM           not enough addressable memory.  Make sure you are

                          unlocking, locked blocks.


          NOVM            not enough virtual memory.


          NOVMT           not enough virtual memory table space.  Try

                          increasing the value of _swp_size.


          DSKERR          problem with disk swap.  Probably out of disk

                          space.


          DSKWARN         Disk swap space safety zone used. Application is

                          seriously low on disk space.


          XMERR           problem with extended memory swap.


          ISFREE          attempt to free, freed pointer.


          NOPTR           attempt to use invalid pointer.


          NOLK            attempt to unlock, an unlocked block.


          LKOVR           lock count overflow.  Make sure you are

                          unlocking, locked blocks.


          HEAPBAD         heap is corrupted.  Try using _HEAPDEBUG or

                          _HEAPTRACE to narrow down the problem.


          Any heap operation which fails may set the MoreHeap error flag,

          obtainable through mherr().  In general, you should validate most

          calls to MoreHeap functions by checking their return values and

          or calling mherr() to determine success or failure.


          mherr() returns 0, if no error has been encountered since the

          last call to mherr().












                                         80




          MoreHeap                                  Reference Manual  10



          10.
          10.
          10.  Reducing executable size
               Reducing executable size
               Reducing executable size


          The maximum code size that you can add to your application is

          approximately 20K.  (That includes debugging functions which

          would be removed in an end user application.)


          If you eliminate debug functions your code will increase about

          12K.


          If you eliminate virtual memory and the debugging functions your

          application size will increase about 8K.


          If you eliminate 640K to 1MB features of MoreHeap and just use it

          for its space efficient heap management techniques your

          application will grow about 4K.


          To eliminate the virtual memory manager link in the object file

          NSWPCCCM.OBJ. Where CCC refers to the compiler TC2, TCP, MC6, or

          AZT and M refers to the memory model (S)mall or (L)arge.


          To eliminate the extended memory functions, including

          swap-to-disk, high memory area access, and upper memory blocks,

          link in the object file NXMMMMMC.OBJ.  Where CCC refers to the

          compiler TC2, TCP, MC6, or AZT and M refers to the memory model

          (S)mall or (L)arge.


          To eliminate the disk swapping functions link in the object file

          NDSKMMMC.OBJ.  Where CCC refers to the compiler TC2, TCP, MC6, or

          AZT and M refers to the memory model (S)mall or (L)arge. You do

          not need to link this in if you are linking in NSWPCCCM.OBJ.


          To eliminate the video ram functions link in the object file

          NVIDMMMC.C.  Where CCC refers to the compiler TC2, TCP, MC6, or

          AZT and M refers to the memory model (S)mall or (L)arge.


          To eliminate the expanded memory features, both the EMM page

          frame and the swap to expanded memory, link in the object file

          NEMMMMMC.OBJ. Where CCC refers to the compiler TC2, TCP, MC6, or

          AZT and M refers to the memory model (S)mall or (L)arge.


          Based on the way your linker resolves dependencies you may find

          that despite linking in the above object files you executable

          size has not decreased. If this happens relink with the MAP

          feature. Review the map and see if virtual memory functions are

          being linked in. If this is the case, create a new version of the

          library that excludes the virtual memory manager OBJs and

          includes the NSWPCCCM.OBJ file. Batch files MHNSCCCM.BAT have

          been included to help you create the new versions of the library.

          Execute the batch file for the appropriate compiler and memory

          mode, where CCC refers to the compiler and M refers to the memory

          model. When completed they will create a new version of the

          library MHNSCCCM.LIB. Once you have created the non-virtual

          memory versions of the library relink using the new library name.



                                         81




          MoreHeap                                  Reference Manual  11



          11.
          11.
          11.  Technical Support
               Technical Support
               Technical Support


          Registered users may obtain technical support Monday-Friday

          9:00AM to 5:00PM EST.  Support is available via:


               .    Compuserve, e-mail to account 72330,705.


               .    Voice, (609) 924-6793


               .    BBS, (609) 683-7701 (300/1200/2400, N-8-1)


          Please provide your name and registration number and a detailed

          description of your problem or question.  In the event of a

          problem also provide your compiler manufacturer and version

          number, computer hardware configuration, and the contents of your

          autoexec.bat and config.sys files.








































                                         82




          MoreHeap                                  Reference Manual  12



          12.
          12.
          12.  Registration
               Registration
               Registration


          MoreHeap Registration


          To obtain information on updates and receive technical support

          please fill out this form and mail to:


          SeaBreeze Software

          Route 518

          Skillman, New Jersey 08558

          USA


          Name  :____________________________________________________


          Street  :__________________________________________________


          City  :_________________________  State : _________________


          Zip Code :_______________ Phone Number :___________________


          Country : _________________________________________________


          Email address : ___________________________________________


          Where did you purchase MoreHeap?:


          ___________________________________________________________


          When?:


          ___________________________________________________________


          Serial Number? (on the diskette):


          ___________________________________________________________





















                                         83