Обработать исключение нарушения прав доступа в С++ Builder?

Я пытаюсь сделать:

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

Я думал, что это должно перехватывать исключение нарушения доступа и обрабатывать его, отображая сообщение об ошибке.

Но почему-то я становлюсь простым

Нарушение доступа

сообщение вместо полного

Нарушение прав доступа XXX в модуле YYY. Пишу по адресу ZZZ.

Кстати, подпрограмма ExceptObject() по какой-то странной причине возвращает NULL.

Что мне здесь не хватает?


person Community    schedule 05.06.2009    source источник
comment
Вы видите только Access Vialotion, потому что так оно и должно работать. RTL не сохраняет все данные об исключении в выбрасываемом объекте EAccessViolation. Что касается ExceptObject(), вы не сказали, какую версию C++Builder вы используете. Известно, что ExceptObject() и ExceptAddr() содержат ошибки в старых версиях C++.   -  person Remy Lebeau    schedule 16.06.2009


Ответы (4)


В BCB5 перехват EAccessViolation работает, например:

 #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);} }

Обратите внимание, что class_name специфичен для этого проекта и, вероятно, должен быть заменен на AnsiString(this->ClassName) или опущен. Также я переключил этот код с тихой регистрации в базу данных на отображение MessageBox. Я просто оборачиваю код, где я наблюдал AV, в AV_TRY... AV_CATCH.

person insignis    schedule 14.09.2010

См. запись в блоге MSDN на тему Смешивание SEH. и исключения C++. Это два разных типа исключений. Попытка поймать структурированное исключение, сгенерированное ОС, как исключение C++, не является правильным выходом из коробки. Уточните этот момент, указав эту публикацию о том, что вы этого не делаете .

Выявление нарушений прав доступа может быть хорошей целью, но вы можете захотеть сделать это только в контексте отладки. Выявление нарушений прав доступа (или других серьезных исключений) в производственном коде и попытка их обработки редко приводят к правильной работе.

person Kris Kumler    schedule 05.06.2009

Стандартный C++ не указывает, что разыменование указателя NULL вызывает исключение - он говорит, что это приводит к неопределенному поведению. На платформах Windows вода несколько запутана структурированной обработкой исключений Windows. Это не имеет ничего общего с обработкой исключений C++, за исключением того, что некоторые среды выполнения C++ могут преобразовывать эти исключения в исключения C++. Однако код, который зависит от таких переводов, не является переносимым.

person Community    schedule 06.06.2009

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
}

Однако вы можете использовать структурированную обработку исключений (SEH), чтобы перехватывать все исключения C++. Поскольку исключения C++ - это просто реализация на основе классов, основанная на SEH.

person ralphtheninja    schedule 06.06.2009
comment
Нет, это ошибка seg, и даже catch(...) не сможет поймать. - person Sesh; 21.03.2010