2006-04-13

Allocating memory and further thoughts on the Singleton Pattern

In all earnest, allocating memory is a prime case of "Damn'd if you do, and damn'd if you do not." On one hand, you spend time programming allocation checking for a 200 K-byte utility that will be the only thing running on a system with 2 G-bytes of RAM. On the other hand, you find out the hard way about the lack such checks when the utility recursively takes over the system's memory during the demo before the boss and very important clients 2 and 3.

The current standards for C++ require that the new operator throws a bad_alloc exception when things go wrong during memory allocation. Compilers can be made aware of this exception by including the 'new' header file while 'using namespace std;' (Sorry, angle brackets are still awkward under Blogger.)
Thus;
bool Setup(void)
{
int *fields;

try{

fields = new int[NUM_RECORDS];

}
catch(bad_alloc e){

return false;

}

// do something

return true;

}

This will allow the program to fail nicely and handle the situation, without crashing the system.

PS. C++ also allows new NOT to throw an exception, but the only reason I can see for this is to allow new to be used in constructors. But I could be wrong.

With respect to Singletons, this means that the Singleton instance can be allowed to fail (return NULL) in case of memory issues. The other side to this is that these kind of memory failures need to be handled as well.Take a look at how Microsoft handles the situation in its View-Documents architecture.
In Release executables, the View uses an inline GetDocument() function that returns a Document pointer that is re-cast into a pointer of the program's specific Document class. In Debug executables, this GetDocument() function first ASSERTs that the program's Document is correctly derived before returning the pointer.

The only cause for concern that might spring up is that when using a Singleton instance in serveral different classes, what happens to version control?

No comments: