## BUG: __Huge New Operator Fails with Variable Size

Q111754

    1.00 1.50
    WINDOWS
    kbtool kbbuglist

    ---------------------------------------------------------------------
    The information in this article applies to:

     - The Microsoft C/C++ Compiler (CL.EXE) included with:
        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    ---------------------------------------------------------------------

    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:

     - If the lower order word is 0 (zero), the call to new will return NULL.

     - If the lower order word is nonzero, then the call will return a valid
       pointer but the block of memory allocated will be smaller than
       requested.

    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
Issue type : kbbug
Technology : kbVCsearch kbAudDeveloper kbCVCComp

Last Reviewed: May 5, 2001 © 2001 Microsoft Corporation. All rights reserved. Terms of Use.