void Function()
{
try
{
// allocate resource
}
catch(Exception e) // some specific Exception
{
// deallocate resource - duplicated
}
catch (...) // generic Exception
{
// deallocate resource - duplicated
}
// deallocate resource - when function succeeds
}
Is that the correct and only way of using exceptions in this situation? Is there a way to place all the deallocation routines in one block, much like SEH (Structured Exception handling) __finally, or even Java, where finally keyword is available?
Note: SEH does not allow objects inside their try/catch that have destructors so it cannot be used with classes.
Mental block with exceptions
I have this confusion about SEH and exceptions, which I hope somebody can answer me..
I use a mixture of C and C++ style coding.. C for win32 calls, classes for others..
My problem:
try, throw, catch in C++ are better suited for objects as during unwinding, the destructors are called automatically.
However, the try, catch doesn''t work nicely with functions that doesn''t use classes, like in most win32 calls
So if I have to manually deallocate resource, it means the deallocation routines have to be duplicated for each catch statement and the end of the function, like so
Try this:
Make sure that code works (with a console app?) before using it extensively.
A really good way to avoid duplicating cleanup code is to use objects on the stack that deallocate their own memory, so as their destructors go out of scope, the memory is deallocated. There is almost always a way of wrapping heap memory with a stack object.
You could try auto_ptr, but it does use delete and not delete[] so it won''t handle arrays properly.
- null_pointer
Sabre Multimedia
void Function()
{
try
{
// allocate resource
// deallocate resource - when function succeeds (#1)
}
catch(Exception e) // some specific Exception
{
// handle exception
throw; // now caught by catch(...) for deallocation
}
catch (...) // generic Exception
{
// deallocate resource (#2)
throw; // throw it up to the function caller
}
}
Make sure that code works (with a console app?) before using it extensively.
A really good way to avoid duplicating cleanup code is to use objects on the stack that deallocate their own memory, so as their destructors go out of scope, the memory is deallocated. There is almost always a way of wrapping heap memory with a stack object.
You could try auto_ptr, but it does use delete and not delete[] so it won''t handle arrays properly.
- null_pointer
Sabre Multimedia
Thanks..
but notice you still have to have two deallocation routines, which is not as "clean" as the __finally keyword (which is executed regardless an exception is thrown or not)
It is not possible(??) to make a stack based allocation when it comes to win32 calls like GetDC()/ ReleaseDC()..
Oh well, it seems like a design flaw in C++..
but notice you still have to have two deallocation routines, which is not as "clean" as the __finally keyword (which is executed regardless an exception is thrown or not)
It is not possible(??) to make a stack based allocation when it comes to win32 calls like GetDC()/ ReleaseDC()..
Oh well, it seems like a design flaw in C++..
May 16, 2000 08:48 PM
You can''t have objects with destructors inside SEH code. That''s one of the reasons why SEH is more efficient than C++ or MFC exception handling.
null_pointer was incorrect in his first post. using throw will NOT cause another exception handler in the same block to catch the exception ... it will throw the exception OUT of the block, to be caught at the end of an external try/catch set. see below for details
try // 1
{
try // 2
{
//error here ... throws ExpClassA
}
catch(ExpClassA e)
{
//error first caught here
throw;
}
catch(...)
{
// nothing caught here ... never called
}
}
catch(...)
{
// rethrown error caught here
}
try // 1
{
try // 2
{
//error here ... throws ExpClassA
}
catch(ExpClassA e)
{
//error first caught here
throw;
}
catch(...)
{
// nothing caught here ... never called
}
}
catch(...)
{
// rethrown error caught here
}
Void, try this -- a very simple encapsulation of GetDC/ReleaseDC.
There''s still many ways. Happy coding.
class DC{public: DC (HWND hwnd) : _hwnd(hwnd), _hdc(::GetDC (hwnd)) {} ~DC () { ::ReleaseDC (_hwnd, _hdc); } operator HDC () { return _hdc };protected: HDC _hdc; HWND _hwnd;};// somewhere in the program body....try{ ... DC dc(hwnd); // some throw happen... // but no worries, the DC class release itself.}catch (...){ // blah blah...}
There''s still many ways. Happy coding.
"after many years of singularity, i'm still searching on the event horizon"
Oh yes, Sai, you are correct there..
Derek, thanks.. the GetDC/ReleaseDC was only a simple call that is frequently used.. but wait.., you mean I have to write a class for each type of heap allocation I make?? Sounds like a lot of work to me..
Derek, thanks.. the GetDC/ReleaseDC was only a simple call that is frequently used.. but wait.., you mean I have to write a class for each type of heap allocation I make?? Sounds like a lot of work to me..
Most probably yes. But I could count them with my hand, there's not much after all. Most are Lock/Unlock, GetDC/ReleaseDC (Windows & DirectX), Open/Close (usually files).
If you want to grow beautiful flowers, you need to get your hand dirty.
BTW, I never used __finally . Is it a standard or MS Specific? And where could I read something about SEH?
Edited by - DerekSaw on May 16, 2000 12:16:55 AM
If you want to grow beautiful flowers, you need to get your hand dirty.
BTW, I never used __finally . Is it a standard or MS Specific? And where could I read something about SEH?
Edited by - DerekSaw on May 16, 2000 12:16:55 AM
"after many years of singularity, i'm still searching on the event horizon"
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement