KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q42596: BASIC’s SETMEM Doesn’t Free C Far Allocation; _fmalloc, _ffree

Article: Q42596
Product(s): See article
Version(s): 4.00 4.00b 4.50
Operating System(s): MS-DOS
Keyword(s): ENDUSER | SR# S890227-157 B_BasicCom S_C S_QuickC | mspl13_basic
Last Modified: 21-DEC-1989

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:

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.

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

#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

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.