views:

1686

answers:

4

I'm trying to do:

try{
    int * i = NULL;
    *i = 3;
}catch(Exception &Err){
    ShowMessage(Err.Message);
}

I though that this should catch access violation exception and handle it by displaying an error message.

But for some reason I get simple 'Access Violation' message instead of full one: 'Access Violation XXX in module YYY. Writing at address ZZZ'. BTW, ExceptObject() routine returns NULL for some strange reason.

What am I missing here?

+1  A: 

See the MSDN blog entry on Mixing SEH and C++ Exceptions. These are two different types of exceptions. Trying to catch a structured exception, generated by the OS, as a C++ exception isn't the correct way out of the box. Temper this bit with this posting on not doing that.

Catching access violations can be a nice goal -- but something you may want to do within the context of debugging only. Catching access violations (or other major exceptions) in production code and trying to handle them is seldom going to result in correct operation.

Kris Kumler
A: 
try {
    int * i = NULL;
    *i = 3;
}
catch (...) {
    // This would catch the access violation but you don't have any more
    // information of what has gone wrong
}

You can however, use structured exception handling (SEH) to catch all C++ exceptions. Since C++ exceptions are just a class based implementation based on SEH.

Magnus Skog
No it is a seg fault and even catch(...) will not be able to catch.
Sesh
A: 

Standard C++ does not specify that dereferencing a NULL pointer throws an exception - it says it results in undefined behaviour. On Windows platforms, the water is muddied somewhat by Windows Structured Exception Handling. This has nothing to do with C++ exception handling, except that some C++ run-times may translate these excptions into C++ exceptions. However, code that depends on such translations is not portable.

anon
A: 

In BCB5, catching an EAccessViolation works, e.g.:

 #define AV_TRY { try {

 #define AV_CATCH } catch(EAccessViolation &av) {Application->MessageBox((("Access Violation caught: " + string(__FILE__) + "; " + string(__FUNC__) + "; " + IntToString(__LINE__) + "\n\n") + av.Message.c_str()).c_str(), ("Program Error in " + string(class_name.c_str())).c_str(), MB_OK);} }

Note that class_name is specific to this project and should probably be replaced by AnsiString(this->ClassName) or left out. Also I've switched this code from logging silently to a database, to showing a MessageBox. I just wrap code where I've observed AVs in an AV_TRY ... AV_CATCH.

insignis