Microsoft KB Archive/42596

= Basic's SETMEM Doesn't Free C Far Allocation; _fmalloc, _ffree =

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 &quot;_fmalloc&quot; and &quot;_ffree&quot; functions. This is expected behavior for the following reasons:


 * 1) 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.
 * 2) 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 &quot;halloc&quot; and &quot;hfree&quot; 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, &quot;Memory Management: A Two-Step Process,&quot; &quot;The Waite Group's Microsoft C Bible.&quot;

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. */ /***********************************************************/


 * 1) include 
 * 2) include 

void HugeMemTest(void) { long huge *lalloc; printf(&quot;Inside of C routine\n&quot;);

lalloc = (long huge *)halloc(10000L,sizeof(long)); if (lalloc == NULL) printf(&quot;\nInsufficient memory available\n&quot;); else printf(&quot;Memory successfully allocated\n&quot;); hfree(lalloc);

printf(&quot;Leaving C routine\n&quot;); }

'*********************************************************** '* 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 &quot;AVAILABLE MEMORY ON THE FAR HEAP:    &quot;, BeforeCall Storage = SETMEM(-50000) PRINT &quot;SIZE OF FAR HEAP AFTER SETMEM:       &quot;, FRE(-1)

' Call to the C routine. PRINT CALL HugeMemTest PRINT : PRINT : PRINT : PRINT

' Report far heap size after call to C. PRINT &quot;SIZE OF FAR HEAP AFTER CALL TO C:    &quot;, FRE(-1) Storage = SETMEM(50000) AfterCall = FRE(-1) PRINT &quot;AVAILABLE MEMORY ON THE FAR HEAP : &quot;, AfterCall

' Report success or failure. IF AfterCall <= BeforeCall THEN PRINT &quot;SETMEM FUNCTIONED PROPERLY&quot; ELSE PRINT &quot;SETMEM DID NOT FUNCTION PROPERLY&quot; END IF END

Additional query words: QuickBas BasicCom

Keywords: KB42596

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.