ID: Q117498
1.00 1.50 WINDOWS kbtool kbbuglist
The information in this article applies to:
- Microsoft Visual C++ for Windows, versions 1.0 and 1.5
A custom-based new(), delete(), and new handler do not receive correct parameters in small-memory or medium-memory models. The new handler's parameters are reversed. For new() and delete(), the offset of the address of the segment, rather than the value of the segment, is pushed onto the stack.
The generated code assumes that __segment is based in DS (default data segment). The code provides a fixup for the segment variable that is the first formal argument.
Switch to the compact-memory, large-memory, or huge-memory model.
Microsoft has confirmed this to be a bug in the products listed at the beginning of this article. We are researching this bug and will post new information here in the Microsoft Knowledge Base as it becomes available.
The sample code below demonstrates this problem. To fix the problem, compile the following sample code using /AC or /AL.
/* Compile options needed: none
*/
#include <iostream.h>
#include <malloc.h>
#include <new.h>
#include <stdlib.h>
#include <string.h>
__segment test_seg;
char __based(test_seg) *a;
void __based(void) *operator new( __segment seg, size_t size);
void operator delete(__segment seg, void __based(void) *ptr);
void test(void);
int NewHandler(__segment s, size_t size )
{
// WARNING: The arguments are backwards.
// s == the size and size == the segment.
cerr << "\n\aCan't allocate " << (size_t)s << " bytes." << endl;
exit(1);
return 0;
}
void main()
{
_set_bnew_handler(NewHandler);
if ((test_seg = _bheapseg(10000)) == _NULLSEG)
{
cout << "bheapseg failure! Bailing..." << endl;
exit(1);
}
test();
}
void test()
{
a = new __based(test_seg) char[100];
if (a == _NULLOFF)
{
cout << "_bmalloc failure." << endl;
return;
}
#if defined (M_I86LM) || (M_I86CM) || (M_I86HM)
strcpy(a, "Greetings");
cout << a << endl;
#else // Small & Medium model
#pragma message ("WARNING: <<small and medium model application>>")
#pragma message ("CRT routines may not reference based data properly.")
#endif
delete a;
}
void __based(void) *operator new( __segment offset, size_t size)
{
unsigned MYDS;
unsigned long addr;
_asm mov ax, ds
_asm mov MYDS, ax
addr = (unsigned long)MYDS;
addr <<= 16;
__segment bseg = *(__segment *)(addr | (unsigned long)offset);
return _bmalloc( bseg, size);
}
void operator delete(__segment offset, void __based(void) *ptr)
{
unsigned MYDS;
unsigned long addr;
_asm mov ax, ds
_asm mov MYDS, ax
addr = (unsigned long)MYDS;
addr <<= 16;
__segment bseg = *(__segment *)(addr | (unsigned long)offset);
_bfree(bseg, ptr);
}
Additional reference words: 1.00 1.50 8.00 8.00c
KBCategory: kbtool kbbuglist
KBSubcategory: CPPIss
Keywords : kb16bitonly
Last Reviewed: July 23, 1997