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
"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
http://zetech.swehli.com
"Lisa Pearlson" <n...@spam.plz> wrote in message
news:%23tQXde7...@TK2MSFTNGP09.phx.gbl...
"Tom Serface" <tser...@msn.com> wrote in message
news:OKikSp7l...@TK2MSFTNGP14.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]
"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.
"James R. Twine" <sp...@jrtwine.com> wrote in message
news:1123069082....@g49g2000cwa.googlegroups.com...
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.
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...
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.