Article ID: 42596
Article Last Modified on 11/21/2006
APPLIES TO
- Microsoft QuickBasic 2.0
- Microsoft QuickBasic 4.0
- Microsoft QuickBASIC 4.0b
- Microsoft QuickBasic 4.5 for MS-DOS
- Microsoft BASIC Compiler 6.0
- Microsoft BASIC Compiler 6.0b
- Microsoft BASIC Professional Development System 7.0
This article was previously published under Q42596
SUMMARY
When reducing far-heap size with the SETMEM statement in Basic and then calling a Microsoft C or QuickC function that does a far allocation, the reduced far-heap memory is not recoverable with SETMEM after returning to the QuickBasic program. C routines do far-memory allocation with "_fmalloc" and "_ffree" functions. This is expected behavior for the following reasons:
- The C _fmalloc obtains memory from MS-DOS. Once far memory is obtained by a C program, it becomes part of the C far heap.
- The _ffree does not release the memory back to MS-DOS, but rather stores it in the C far heap along with a linked-list data structure that C uses to manage its heap space.
Thus, SETMEM cannot recover this memory.
This information applies to Microsoft QuickBasic versions 4.00, 4.00b, and 4.50 for MS-DOS; to Microsoft Basic Compiler versions 6.00 and 6.00b for MS-DOS and MS OS/2; and to Microsoft Basic PDS version 7.00 for MS-DOS and MS OS/2.
MORE INFORMATION
To recover the memory in the Basic program, the C routine should do a huge allocation with the "halloc" and "hfree" functions. The C huge allocation routines differ from the far allocation routines. The halloc function always requests the memory directly from MS-DOS. The hfree function returns the memory directly back to MS-DOS. Once a C routine has executed an hfree, this memory can be recovered from a Basic program with SETMEM.
There is one disadvantage to using huge allocation. With huge allocation, there is no memory management involved on the part of the C routines. This can lead to memory fragmentation if the C routines do repeated allocations and frees.
The C routine should be carefully constructed to avoid this fragmentation. For more information on C memory management, please see page 114, "Memory Management: A Two-Step Process," "The Waite Group's Microsoft C Bible."
Code Example
/***********************************************************/ /* The following C function HugeMemTest can be called from */ /* Basic to demonstrate that huge allocation returns */ /* memory to the Basic program. /* Compile this routine with the medium memory model. */ /* Do not compile with the huge memory model, since this */ /* causes the code not to work and the memory won't be */ /* freed. */ /***********************************************************/ #include <stdio.h> #include <malloc.h> void HugeMemTest(void) { long huge *lalloc; printf("Inside of C routine\n"); lalloc = (long huge *)halloc(10000L,sizeof(long)); if (lalloc == NULL) printf("\nInsufficient memory available\n"); else printf("Memory successfully allocated\n"); hfree(lalloc); printf("Leaving C routine\n"); } '*********************************************************** '* This Basic routine releases memory to DOS using * '* SETMEM. It then calls a C routine that does huge * '* allocation and a huge free. SETMEM is used to recover * '* the memory and success or failure is reported. * '*********************************************************** DECLARE SUB HugeMemTest CDECL () ' Report far heap size before the C call. CLS BeforeCall = FRE(-1) PRINT "AVAILABLE MEMORY ON THE FAR HEAP: ", BeforeCall Storage = SETMEM(-50000) PRINT "SIZE OF FAR HEAP AFTER SETMEM: ", FRE(-1) ' Call to the C routine. PRINT CALL HugeMemTest PRINT : PRINT : PRINT : PRINT ' Report far heap size after call to C. PRINT "SIZE OF FAR HEAP AFTER CALL TO C: ", FRE(-1) Storage = SETMEM(50000) AfterCall = FRE(-1) PRINT "AVAILABLE MEMORY ON THE FAR HEAP : ", AfterCall ' Report success or failure. IF AfterCall <= BeforeCall THEN PRINT "SETMEM FUNCTIONED PROPERLY" ELSE PRINT "SETMEM DID NOT FUNCTION PROPERLY" END IF END
Additional query words: QuickBas BasicCom
Keywords: KB42596