BUG: _vmalloc() May Fail on Block Allocations

Last reviewed: July 22, 1997
Article ID: Q127201
1.50 1.51 1.52 MS-DOS kbprg kbbuglist

The information in this article applies to:

  • The C Run-time, included with: Microsoft Visual C++ for Windows, versions 1.50, 1.51 and 1.52

SYMPTOMS

When using virtual memory allocation function _vmalloc() in the C runtime library, the program may fail on _vmalloc() if all of the following conditions are met :

  • You use _vmalloc() to do block allocation instead of page allocation.
  • You reuse the virtual memory without repeatedly calling _vheapinit() and _vheapterm().
  • You use _vmalloc() to allocate an array of memory blocks that has a minimum of 1000 elements. The pseudo code for the algorithm could resemble this:

    _vheapinit(...);

       // _vmalloc() fails on the second iteration when j=512.
       for ( i=0; i<2; i++ )
       {
         for ( j=0; j<1000; j++ )
           handle[j] = _vmalloc(...);
    
         for ( j=0; j<1000; j++ )
           _vfree( handle[j] );
       }
    
       _vheapterm();
    
    
The program allocates and frees the virtual memory blocks correctly for the first iteration of the outer For loop, but fails on the second iteration of the outer For loop when the inner For loop goes to iteration 512.

RESOLUTION

To work around the problem, use one of these two suggestions:

  • Use page allocation instead of block allocation. This could be done by allocating a memory block with size greater than 2042 bytes. The virtual memory manager adds six bytes for the block header to the size of the allocation and rounds the result up to the next multiple of the virtual page size (2048 bytes).

    -or-

  • Call _vheapinit() and _vheapterm() to reinitialize the virtual memory manager when virtual memory needs to be reallocated. For example:

    for ( i=0; i<2; i++ ) {

         _vheapinit(...);
    

         for ( n=0; n<1000; n++ )
           handle[n] = _vmalloc(...);
    

         for ( n=0; n<1000; n++ )
           _vfree( handle[n] );
    

         _vheapterm();
    
    }

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

Sample Code to Reproduce Problem

/* Compile options needed: None
*/

#include <stdio.h>
#include <stdlib.h>
#include <vmemory.h>

#define NUM_ELEMENT 1000
#define SIZE        2042

_vmhnd_t vm_handle[NUM_ELEMENT];

int main()
{
   int i;
   unsigned long n;
   unsigned hmem = NUM_ELEMENT;
   char __far *pntr;

   printf("\nTest allocating virtual memory");

   // Initializing virtual memory managers.
   if(_vheapinit(0, _VM_ALLDOS, _VM_ALLSWAP)==0)
   {
     printf("\nError initializing virtual memory manager\n");
     exit(-1);
   }

   printf("\nVirtual memory manager initialization done");

   // Allocating virtual memory.
   for ( i=0; i<2; i++ )
   {
     printf("\n\nAllocating memory... ");
     for( n=0; n<hmem; n++ )
     {
       vm_handle[n] = _vmalloc(SIZE);
       if ( vm_handle[n]==_VM_NULL )
       {
         printf("Cannot allocate virtual memory. Entry = %d\n", n);
         _vheapterm();
         exit(-1);
       }
     }
     printf("Done\n");

     // Testing the virtual memory allocation.
     printf("Testing... ");
     for ( n=0; n<hmem; n++ )
     {
       pntr = (char __far *)_vload(vm_handle[n], _VM_DIRTY);
       if( pntr==NULL )
       {
         printf("Error in testing %d", n);
         exit(-1);
       }
     }
     printf("Done\n");

    // Deleting virtual memory allocated earlier.
    for ( n=0; n<hmem; n++ )
      _vfree(vm_handle[n]);

    printf("Memory freed...Done\n");
  }

  _vheapterm();

  return(1);
}

REFERENCES

For more information on virtual memory block allocation and page allocation, please see the following article in the Microsoft Knowledge Base:

ARTICLE-ID: Q93211

TITLE     : INF: _vmalloc() May Allocate Larger Memory Block Than Expected


Additional reference words: 1.50 1.51 buglist8.00
KBCategory: kbprg kbbuglist
KBSubCategory: VirtualMem
Keywords : kb16bitonly


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.

Last reviewed: July 22, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.