Microsoft KB Archive/111754

{|
 * width="100%"|

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