Re: problems with constructor throwing exception
Alberto Ganesh Barbati wrote:
Why don't you just post a code snippet? No matter how hard you describe
it, people will find it difficult to visualize a problem that complex
without reading the code.
// I am forced to take over memory management for my module by
architectural
// constraints. It shouldn't be too much slower than malloc/free.
struct Heap {
// discards all physical blocks held to create the smaller logical
blocks
~Heap ();
// throws an exception if physical memory cannot be obtained
// otherwise, creates a logical block in the heap
// more or less same api as malloc
void* Alloc (size_t size);
// more or less same api as free
void Free (void* p);
};
// policy for objects created on a heap
struct Object {
// never used, provide a throwing implementation
static void* operator new (size_t);
// always used
static void* operator new (size_t, Heap&);
// always used in program
// finds the Heap* in a hidden header
static void operator delete (void*);
// used in internal compiler code when
// the constructor throws??? This would
// imply that any new call in the program
// would generate a hidden try block,
// and I am wondering if this is inline???
static void operator delete (void*, Heap&);
};
struct Node {
...
};
struct NodePool {
NodePool (Heap&);
Node* NewNode (); // can throw
// in lieu of destructor!
// frees the pool back to the heap
void Destroy ();
};
class Graph : public Object {
Heap heap;
NodePool pool;
Node* const entry;
Node* const exit;
public:
Graph (Heap& myheap) :
heap(myheap),
pool(myheap), // can't throw
entry(pool.NewNode()), // can throw
exit(pool.NewNode()) // can throw
{
}
// will never be invoked if 2nd NewNode above
// throws, implying that 1st NewNode causes
// pool growth, but without destructor in Pool
// (by design), the pool leaks.
~Graph ()
{
// since pool has no destructor
// this is the only way it is released
pool.Destroy();
}
};
class SpecialGraph : public Graph {
//... additional pools and members
public:
SpecialGraph (Heap&);
...
};
main {
Heap heap;
// what kind of code does compiler generate
// to match a call to Object::delete if constructor
// throws anywhere??? is it inline???
// does it have a try...catch???
SpecialGraph* graph = new (heap) SpecialGraph(heap);
// NOTE: if the 2nd NewNode throws, there is a temporary
// leak relative to heap that is cleaned up only when
// "heap" is destroyed on scope exit
}
If I am concerned about the heap-relative leak in Graph
constructor, then I can offer a Construct() member
in graph, called just after the "new" call, to create
entry/exit nodes. However, memory errors are "fatal"
and always result in component shutdown, which means
the heap used will be destroyed, therefore no real leak.
My main concern is what kind of code is generated
by new (heap) SpecialGraph(heap). In particular, it would
seem that the compiler has to always go to the trouble of
a hidden try...catch block that invokes the placement delete
operator of Object if the constructor throws. True???
Andy
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]