BUG: __Huge New Operator Fails with Variable Size

ID: Q111754

1.00 1.50 WINDOWS kbtool kbbuglist

The information in this article applies to:

SYMPTOMS

If a variable is used as the size parameter to the __huge new operator, the return value will be NULL or a pointer to a memory block that is smaller than requested.

CAUSE

The problem is that only the lower order word of the variable that is passed as the length parameter will be used. Therefore, if the allocation is less than 64K, the call will be successful. However, if the allocation size is greater than 64K, the call to new will fail as follows:

RESOLUTION

If the variable size is constant (that is, it never changes), then substitute the absolute value as the parameter to the call to new. For example, change the following

   long lSize=0x20000;
   char __huge *pChar = new __huge char[lSize];

to the following:

   char __huge *pChar = new __huge char[0x20000];

A call to _halloc can be used instead. For example, change the following

   /* lSize==0x20000 */ 
   char __huge *pChar = new __huge char[lSize];

to the following:

   char __huge *pChar = (char __huge *) _halloc(lSize,sizeof(char));

NOTE: If using _halloc. be sure to use _hfree instead of delete. Also, you need to include <malloc.h>.

STATUS

Microsoft has confirmed this to be a problem in Microsoft C/C++ for MS-DOS, versions 8.0 and 8.0c. We are researching this problem and will post new information here in the Microsoft Knowledge Base as it becomes available.

MORE INFORMATION

The problem can be seen by generating an assembly listing of the code. Included below is a section of code and the accompanying assembly listing generated by using the /Fc compiler switch:

Sample Code

/*
/ Compile options needed: /Fc
*/ 

#include <iostream.h>

void main(void)
{
 long test=0x20000;
 char __huge * ptr;

 ptr=new __huge char[test];

// ; Line 10
//    *** 000015  b8 01 00        mov ax,OFFSET 1
//    *** 000018  50          push    ax
//    *** 000019  8b 46 f6        mov ax,WORD PTR -10[bp]
//    *** 00001c  8b 56 f8        mov dx,WORD PTR -8[bp]
//    *** 00001f  ba 00 00        mov dx,OFFSET 0
//    *** 000022  52          push    dx
//    *** 000023  50          push    ax
//    *** 000024  e8 00 00        call    ??2@YAPIXKI@Z
//    *** 000027  83 c4 06        add sp,OFFSET 6
//    *** 00002a  89 46 fa        mov WORD PTR -6[bp],ax
//    *** 00002d  89 56 fc        mov WORD PTR -4[bp],dx
//;

 if (ptr!=NULL)
  cout << "Success!";
 else
  cout << "Failure!";
}

This line is the cause of the problem:

//    *** 00001f  ba 00 00        mov dx,OFFSET 0

This destroys the upper word of the length and effectively limits you to allocating only up to 64K.

Additional reference words: 1.00 1.50 8.00 8.00c halloc free KBCategory: kbtool kbbuglist KBSubcategory: CLIss Keywords : kb16bitonly

Last Reviewed: July 23, 1997