Guidelines
List of: Discussion Topic
Subjects: Error Handling
Contents: Application Development Manual

Following are some guidelines for implementing exception handling for memory cleanup These guidelines cover some of the most common situations involved in memory cleanup. There are bound to be other situations that are not covered here. These are only guidelines and individual circumstances may be better handled in other ways.

Instances of classes derived from ENTITY and items pointed to by them do not need to be cleaned up. The bulletin board mechanism will take care of them. Cleaning up items pointed to by ENTITY class instances will almost certainly cause memory access errors.
Simply looking for occurrences of new and delete will not identify all places where exception handling needs to be implemented. Functions that return pointers to allocated memory and instances of classes (such as ENTITY_LIST) that may contain pointers to large amounts of allocated memory should also be identified.

// Local instance of memory consuming class

ENTITY_LIST list;

// Function returns allocated memory

curve_curve_int *cci = int_cur_cur(c1, c2);

Declarations of local instances of classes that may contain pointers to large amounts of dynamically allocated memory that would be freed by their destructors should be moved into a EXCEPTION_BEGIN block.
All memory that the routine would normally free upon successful completion should be freed if an exception occurs.

FOO *foo_array = new FOO[n];

...

delete [] foo_array;


Becomes

EXCEPTION_BEGIN

FOO *foo_array = NULL;

EXCEPTION_TRY

foo_array = new FOO[n];

...

EXCEPTION_CATCH(TRUE)

delete [] foo_array;

EXCEPTION_END

Memory that would be returned or attached to another object should be cleaned up in the EXCEPTION_CATCH block if it could exist for a significant period of time before being returned or attached. Avoid multiple deletion of allocated memory pointed to by class instances to be cleaned up.

FOO *foo_ptr = new FOO(...);

...

BAR *bar_ptr = new BAR(foo_ptr,...);

...

return bar_ptr;


Becomes

BAR *bar_ptr = NULL;

EXCEPTION_BEGIN

FOO *foo_ptr = NULL:

EXCEPTION_TRY

foo_ptr = new FOO(...);

...

bar_ptr = new BAR(foo_ptr,...);

...

EXCEPTION_CATCH(FALSE)

if (bar_ptr == NULL)


delete foo_ptr;

else


delete bar_ptr;

EXCEPTION_END

return bar_ptr;

It is important to keep in mind that several type names (such as bs2_curve and bs3_surface) are actually pointers. Functions that return these types are probably returning pointers to allocated memory.
Exception handling is relatively cheap, but not free. Consider size and duration of memory use when deciding whether to attempt to catch a potential leak.

// A small allocation, quickly attached

FOO *foo_ptr = new FOO(...);

bar.set_foo(foo_ptr);
PDF/APPDEV/06ERR.PDF
HTM/DATA/ACIS/APPDEV/06ERR/0005.HTM