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

'new' keyword

0 views
Skip to first unread message

Lisa Pearlson

unread,
Aug 2, 2005, 7:12:49 PM8/2/05
to
Newbie C++ question. Imagine:

SOMEDATATYPE *p = new SOMEDATATYPE;

does 'new' ever throw a memory exception, or always return NULL if not
enough memory was available?

in other words, is this sufficient:

SOMEDATATYPE* GetNew()
{
SOMEDATATYPE *p = new SOMEDATATYPE;
return p;
}

or do I need to do this:

SOMEDATATYPE* GetNew()
{
SOMEDATATYPE* p = NULL;
try
{
p = new SOMEDATATYPE;
}
catch(CMemoryException* e)
{
e->Delete();
if (p)
{
delete p;
p = NULL;
}
}

return p;
}

In other words, does new always return null when it fails, or is it possible
that it allocates 'some' memory, but throws an exception if not completely?

Lisa


Tom Serface

unread,
Aug 2, 2005, 7:31:41 PM8/2/05
to
I guess the answer is "it depends":

"Beginning in Visual C++ .NET 2002, the CRT's new function (in libc.lib,
libcd.lib, libcmt.lib, libcmtd.lib, msvcrt.lib, and msvcrtd.lib) will
continue to return NULL if memory allocation fails. However, the new
function in the Standard C++ Library (in libcp.lib, libcpd.lib, libcpmt.lib,
libcpmtd.lib, msvcprt.lib, and msvcprtd.lib) will support the behavior
specified in the C++ standard, which is to throw a std::bad_alloc exception
if the memory allocation fails."

Tom

"Lisa Pearlson" <n...@spam.plz> wrote in message
news:%23tQXde7...@TK2MSFTNGP09.phx.gbl...

Mark Randall

unread,
Aug 2, 2005, 7:33:52 PM8/2/05
to
It will always return null if the size of memory cannot be allocated, doing
otherwise would be illogical.

--
- Mark Randall
http://zetech.swehli.com

"Lisa Pearlson" <n...@spam.plz> wrote in message
news:%23tQXde7...@TK2MSFTNGP09.phx.gbl...

Lisa Pearlson

unread,
Aug 2, 2005, 7:57:58 PM8/2/05
to
That seems to relate only to STL buffers.

"Tom Serface" <tser...@msn.com> wrote in message
news:OKikSp7l...@TK2MSFTNGP14.phx.gbl...

Jeff Partch [MVP]

unread,
Aug 2, 2005, 9:01:22 PM8/2/05
to
"Lisa Pearlson" <n...@spam.plz> wrote in message
news:%23tQXde7...@TK2MSFTNGP09.phx.gbl...

I believe that in a standard MFC app 'new' always throws a CMemoryException*
if not enough memory exists to perform the allocation. Since the exception
is thrown during the call to the allocator, 'p' will remain unchanged.
--
Jeff Partch [VC++ MVP]


James R. Twine

unread,
Aug 3, 2005, 7:38:02 AM8/3/05
to
"new" will not "partially allocate" memory and return a pointer to that
partially allocated memory; if it did, you would have no way of knowing
exactly how much was allocated.

"new" will throw an exception or return NULL when it cannot allocate
all required memory (what happens or which exception is thrown depends
on your environment and situation).

"new" will also "pass along" any exception that might be thrown by the
constructor of an object. So you can still get exceptions from the
point where you use "new" even though your environment may be
configured to have "new" return NULL if it fails to allocate.

In that case, any "fully constructed" member objects that were created
by the underlying object's constructor will be destructed, and the
memory allocated by "new" will be freed. The object's constructor will
not be called until the memory required by the object proper (meaning
"sizeof( TheObject )") has been allocated by "new" successfully. This
prevents you from getting a "partially constructed" object.

Note that the situation is very different when using "placement new",
because since you have to handle memory allocation and call
constructors (and destructors) explicitly, you have to perform
constuctor-based exception handling yourself. If you are not careful,
it is possible to end up with a partially constructed object in memory,
that may have been partially cleaned up, and you have to be careful not
to try to use it.

Peace!

-=- James.

Alexander Grigoriev

unread,
Aug 3, 2005, 9:42:47 AM8/3/05
to
I think, exception handling when using placement new is no different from
constructing a local object. The same unwinding will be performed.

"James R. Twine" <sp...@jrtwine.com> wrote in message
news:1123069082....@g49g2000cwa.googlegroups.com...

James R. Twine

unread,
Aug 3, 2005, 10:51:12 AM8/3/05
to
The same unwinding will take place, yes, but consider that under normal
(non-placement) scenarios, "new" kinda works like this:

1: Allocate space for the object proper
2: Call constructor for object placed into allocated memory
2a: If an exception is thrown from the constructor, handle it, cleanup
the object, free the memory allocated for the object in step #1, and
re-throw the exception up the stack.

Now, suppose you are using "placement new" in a object cache that
manages larger blocks of memory and creates multiple objects in
"subblocks" of the larger blocks of memory. When a object is
requested, you either return an already-created one, or you have to
instantiate one in an available subblock. So you might have to manage
where your next free subblock is. Now, suppose you are constructing a
new object in a subblock, but its constructor raises an exception.
Before allowing it up the stack, you might have to adjust your "next
free subblock" location so that the subblock could be reused by the
next instantiation, and then do whatever other behaviour would be
required of your cache implementation, like eating the exception and
returning NULL, or re-throwing it back up the stack.

Besides, when doing an object cache like this, you usually
pre-construct a number of objects at once, so if you just allowed an
exception to propogate outward, you would not finish construction of
all of the objects in your pool/cache.

Peace!

-=- James.

Alexander Grigoriev

unread,
Aug 4, 2005, 12:24:04 AM8/4/05
to
You're mixing two different concepts: custom allocator and object cache.

If you have object cache, the problem is not related to new/delete: the
objects are already initialized and new/delete is not called for them.

If you have lookaside list for memory blocks, you have a custom allocator.
If you call your special form of operator new, and exception is thrown, a
matching operator delete will be called, which is supposed (you're supposed
to make sure) to properly dispose of the memory block (return it to the
lookaside list).

If you build an object cache, you can use a custom new/delete pair to
allocate them from a big block.
If an exception is thrown in the middle of constructor, it's job of the
constructor unwinding code to call destructor for all constructed
subobjects. As a result, you end up with an uninitialized memory block
again.

"James R. Twine" <sp...@jrtwine.com> wrote in message

news:1123080672.9...@g43g2000cwa.googlegroups.com...

James R. Twine

unread,
Aug 4, 2005, 9:00:33 AM8/4/05
to
Perhaps I am, but the point of the demonstration/example was not how to
implement the perfect object cache or custom allocator.

It describes a scenario where you *might* have to do some additional
exception handling/manipulation in order to reuse the block of memory
you were trying to instantiate the object into. It was only meant as
an example, regardless of how many concepts it mixes up.

An object cache implementation, *if* it manages the overall lifetime of
its object, has to manage calls to the object's constructors and
destructors at some point. Some do, some do not. My example did.

Peace!

-=- James.

0 new messages