Cleanup after an exception

next - skip - up - start

The exception mechanisms in newmat are based on the C functions setjmp and longjmp. These functions do not call destructors so can lead to garbage being left on the heap. (I refer to memory allocated by new as heap memory). For example, when you call

   Matrix A(20,30);
a small amount of space is used on the stack containing the row and column dimensions of the matrix and 600 doubles are allocated on the heap for the actual values of the matrix. At the end of the block in which A is declared, the destructor for A is called and the 600 doubles are freed. The locations on the stack are freed as part of the normal operations of the stack. If you leave the block using a longjmp command those 600 doubles will not be freed and will occupy space until the program terminates.

To overcome this problem newmat keeps a list of all the currently declared matrices and its exception mechanism will return heap memory when you do a Throw and Catch.

However it will not return heap memory from objects from other packages. If you want the mechanism to work with another class you will have to do four things:

  1. derive your class from class Janitor defined in except.h;
  2. define a function void CleanUp() in that class to return all heap memory;
  3. include the following lines in the class definition
          public:
             void* operator new(size_t size)
             { do_not_link=TRUE; void* t = ::operator new(size); return t; }
             void operator delete(void* t) { ::operator delete(t); }
    
  4. be sure to include a copy constructor in you class definition, that is, something like
          X(const X&);
    
Note that the function CleanUp() does somewhat the same duties as the destructor. However CleanUp() has to do the cleaning for the class you are working with and also the classes it is derived from. So it will often be wrong to use exactly the same code for both CleanUp() and the destructor or to define your destructor as a call to CleanUp().