I read somewhere that the 'new' operator will never return NULL -
but will throw an exception instead.
Is this true?
If it does throw a memory exception & I don't catch it what will mfc
do? (Should I still check the result?)
I should that exception handling is not may strong point -
especially in MFC.
Thanx.
If there is insufficient memory for the allocation request, by default
operator new returns NULL. You can change this default behavior by
writing a custom exception-handling routine and calling the
_set_new_handler run-time library function with your function name as
its argument.
Also, you can override default operator new function to let new do
whatever you want.
Evan
In VC++. Jake, the C++ standard requires throwing
an exception. VC++ does not implement this by
default, since much existing code expects the
prior behavior, returning NULL.
>You can change this default behavior by
>writing a custom exception-handling routine and calling the
>_set_new_handler run-time library function with your function name as
>its argument.
And Evan has just explained how to implement
the required throw, if you so desire.
> I read somewhere that the 'new' operator will never return NULL -
No one else has said it, so I will.
Look for documentation of the nothrow option. It allows one to create
code that expects a NULL return value (ie non-standard).
--------------
Richard Cavell
Melbourne University Medical Student, Debater, Chess Player, etc.
- r.ca...@ugrad.unimelb.edu.au
Celebrating the Micro$oft breakup.
Newsgroups - Please keep it on the group, and copy your replies to me via
email. (Server problems).
There is a series of document on the MSDN web site all about this.
then select columns and Deep C++.
"Jake Montgomery" <jac...@hotmail.com> wrote in message
news:3984C291...@hotmail.com...
> Hi,
>
> I read somewhere that the 'new' operator will never return NULL -
> Hi,
>
> I read somewhere that the 'new' operator will never return NULL -
> but will throw an exception instead.
> Is this true?
ANSI Standard C++ declares this to be true, but VC++ does not follow
the standard, and new does in fact return 0 on failure for your
compiler.
However, for standards-compliant operator new to not throw an
exception, you can pass it an argument, std::nothrow, and it won't
throw an exception on failure. For example:
X * x = new(std::nothrow) X; // will not throw.
But you don't need this when the compiler won'd throw anyway. :)
> If it does throw a memory exception & I don't catch it what will mfc
> do? (Should I still check the result?)
It throws (or is supposed to throw) an exception of type
std::bad_alloc. I don't know what MFC does with exceptions (never used it.)
> I should that exception handling is not may strong point -
> especially in MFC.
You probably don't have to worry about it since VC++ doesn't throw.
But keep in mind that when new doesn't throw an exception, that is
VC++ specific (though old C++ compilers also behave this way) and will
break quite severely if you port your non-MFC VC++ code to a C++
compiler that does throw.
--
Chris
If so, AfxNewHandler is your new handler and it simply calls
AfxThrowMemoryException. Which does exactly that.
Jake Montgomery wrote:
>
> Hi,
>
> I read somewhere that the 'new' operator will never return NULL -
> but will throw an exception instead.
> Is this true?
>
> If it does throw a memory exception & I don't catch it what will mfc
> do? (Should I still check the result?)
> I should that exception handling is not may strong point -
> especially in MFC.
>
> Thanx.
_PNH pnhOldHandler = AfxSetNewHandler(&AfxCriticalNewHandler);
pWhatever = new whatever;
AfxSetNewHandler(pnhOldHandler);
MFC actually pre-allocates a bunch of memory on program initialization.
They refer to it as the "safety pool buffer". The AfxCriticalNewHandler
will attempt to fetch memory from this buffer.
Thanks
Richard Jones
void CNewtestDlg::OnOK()
{
int x=0;
// TODO: Add extra validation here
struct L
{
double
a01,b01,c01,d01,e01,f01,g01,h01,i01,j01,k01,l01,m01,n01,o01,p01,q01,r01,s01,
t01,u01,v01,w01,x01,y01,z01;
double
a02,b02,c02,d02,e02,f02,g02,h02,i02,j02,k02,l02,m02,n02,o02,p02,q02,r02,s02,
t02,u02,v02,w02,x02,y02,z02;
double
a03,b03,c03,d03,e03,f03,g03,h03,i03,j03,k03,l03,m03,n03,o03,p03,q03,r03,s03,
t03,u03,v03,w03,x03,y03,z03;
double
a04,b04,c04,d04,e04,f04,g04,h04,i04,j04,k04,l04,m04,n04,o04,p04,q04,r04,s04,
t04,u04,v04,w04,x04,y04,z04;
double
a05,b05,c05,d05,e05,f05,g05,h05,i05,j05,k05,l05,m05,n05,o05,p05,q05,r05,s05,
t05,u05,v05,w05,x05,y05,z05;
double
a06,b06,c06,d06,e06,f06,g06,h06,i06,j06,k06,l06,m06,n06,o06,p06,q06,r06,s06,
t06,u06,v06,w06,x06,y06,z06;
double
a07,b07,c07,d07,e07,f07,g07,h07,i07,j07,k07,l07,m07,n07,o07,p07,q07,r07,s07,
t07,u07,v07,w07,x07,y07,z07;
double
a08,b08,c08,d08,e08,f08,g08,h08,i08,j08,k08,l08,m08,n08,o08,p08,q08,r08,s08,
t08,u08,v08,w08,x08,y08,z08;
double
a09,b09,c09,d09,e09,f09,g09,h09,i09,j09,k09,l09,m09,n09,o09,p09,q09,r09,s09,
t09,u09,v09,w09,x09,y09,z09;
double
a10,b10,c10,d10,e10,f10,g10,h10,i10,j10,k10,l10,m10,n10,o10,p10,q10,r10,s10,
t10,u10,v10,w10,x10,y10,z10;
};
MessageBox("before declaring pointers");
L *aa[100000];
MessageBox("befor loop, new");
while(1)
{
aa[x]=new L;
if(aa[x]==NULL)
{ MessageBox("new returned null");
//while(1)MessageBeep(-1);
}// end if
x++;
if(x==100000)break;
}
MessageBox("new did not fail");
x=0;while(1){delete aa[x];x++;if(x==100000)break;}
CDialog::OnOK();
}
Richard John Cavell wrote in message ...
>On Sun, 30 Jul 2000, Jake Montgomery wrote:
>
>> I read somewhere that the 'new' operator will never return NULL -
>
VC does in fact return NULL (and thus does not follow the standard).
You can use the '_set_new_handler' function to make the standard new
operator behave as in the standard, to make sure your programs won't break
if ported from standard C++. (Personally, I also prefer to avoid checking
for NULL returns everywhere I use new).
Include this code, and call '_set_new_handler(StandardNewHandler)' as early
as possible in your app:
int __cdecl StandardNewHandler(size_t size)
{
throw(whatever_object_you_want);
}
best regards,
Christopher Frenning
Christopher Frenning, Program Manager, FotoWare AS
christophe...@fotoware.com, http://www.fotoware.com
I'm wary of initializing the new handler in a static variable because the
linker may not realize it shouldn't strip the code. I just tried it in VC++
6.0 sp4 and found that including a NewHandler.obj (from the article) with my
application works fine but that, if I put that object in a static win32
library and then link the library with my application, the NewHandler.obj
isn't included. It has to be included explicitly with a linker /include
option either on the command line or in a #pragma. In short, if you try to
make it standard that new() throw std::bad_alloc by putting the object in a
library, anyone using it has to remember to set some ugly /include switches.
In my case, it was
#pragma comment(linker,"-include:?my_new_handler@@YAHI@Z")
If you forget it, your code isn't throwing exceptions, and you are up a
crick.
You can still get cross-platform compatibility with a little overcoding:
try {
a = new char[10000];
if (a==0) throw std::bad_alloc;
b = new char[10000];
if (b==0) throw std::bad_alloc;
} catch (std::bad_alloc) {
cleanup;
}
Both VC++ and a compiler nice enough to throw bad_alloc would be fine with
this code.
Hope All Is Well,
Drew
> I'm wary of initializing the new handler in a static variable because the
> linker may not realize it shouldn't strip the code. I just tried it in VC++
> 6.0 sp4 and found that including a NewHandler.obj (from the article) with my
> application works fine but that, if I put that object in a static win32
> library and then link the library with my application, the NewHandler.obj
> isn't included. It has to be included explicitly with a linker /include
> option either on the command line or in a #pragma. In short, if you try to
> make it standard that new() throw std::bad_alloc by putting the object in a
> library, anyone using it has to remember to set some ugly /include switches.
Where I work, the common makefile simply causes std_new.obj, which has
the static lifetime object w/ ctor in it, which works fine, with no
#pragmas. Is there any particular reason to prefer doing the extra
step of turning it into a lib? I only have the one object file that
is included _everywhere_.
So just don't lib it.
--
Todd Greer <tgr...@acm.org>