Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can new return NULL?

170 views
Skip to first unread message

Jake Montgomery

unread,
Jul 30, 2000, 3:00:00 AM7/30/00
to
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.


Evan Li

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Jake,

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

Ron Ruble

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to

Evan Li wrote in message <3984CD32...@gdc.lucent.com>...

>If there is insufficient memory for the allocation request, by default
>operator new returns NULL.

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.


Richard John Cavell

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to Jake Montgomery
On Sun, 30 Jul 2000, Jake Montgomery wrote:

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

Jason Mullings

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
I think the C++ standard says new should throw an exception ( bad_alloc )
however I seem to remember reading that the MS implementation does not do
this.

There is a series of document on the MSDN web site all about this.

WWW.MSDN.MICROSOFT.COM

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 -

Chris Uzdavinis

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Jake Montgomery <jac...@hotmail.com> writes:

> 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

Douglas Peterson

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Since this IS the MFC forum you must be using MFC.

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.

Douglas Peterson

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to
Also note that you too can take advantage of MFCs "critical memory
allocator" like this:

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

Richard Jones

unread,
Jul 31, 2000, 3:00:00 AM7/31/00
to

Hello Richard;
Just for kicks, I wrote this to test new returning null. I now see your
posting on std:nothrow so I will see if it works.

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

Christopher Frenning

unread,
Aug 1, 2000, 3:00:00 AM8/1/00
to
>>
>> I read somewhere that the 'new' operator will never return NULL -
>> but will throw an exception instead.
>> Is this true?
>>

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

Andrew Junkyard Dolgert

unread,
Aug 3, 2000, 3:00:00 AM8/3/00
to

Sample code is at
http://support.microsoft.com/support/kb/articles/Q167/7/33.ASP . They
initialize the new handler in the constructor of a class statically
instantiated in the lib segment so the new handler is installed early and
transparently.

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


Todd Greer

unread,
Sep 1, 2000, 10:25:11 AM9/1/00
to
"Andrew Junkyard Dolgert" <aj...@cornell.edu> writes:

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

0 new messages