Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обработка ошибок, Способы обработки нештатных ситуаций 
:(
    Опции темы
AndyY
  Дата 8.5.2004, 11:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



К примеру надо написать такоe:

Код
HKEY h;
::RegOpenKey( ..., &hkey );
HANDLE hfile = ::CreateFile( ... )
HANDLE hmap = ::CreateFileMapping
void *ptr = MapViewOfFile( hmap, ... )
::RegQueryValueEx( hkey, ...ptr, ... );

::UnmapViewOfFile( ptr )
::CloseHandle( hmap );
::CloseHandle( hfile )

::RegCloseKey( hkey );


Очевидно, что большинство этих функций могут вернуть ошибку.

Вопрос: как вы пишите код чтобы эти ошибки корректно обработать?


--------------------
PM MAIL WWW   Вверх
Step
Дата 8.5.2004, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: 5
Всего: 25



try
{
Твой проблемный код
}
catch (CFileException *e) или другой клас смотри мсдн
{
Обработка ошибки
}

Добавлено @ 11:57
Пользуйтесь поиском и факю


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
AndyY
Дата 8.5.2004, 12:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



вы используете для каждого объекта (блока памяти, ключа реестра, файла итд) класс - обертку или просто удаляете их после catch (...)?

подчеркну, что мне интересны способы, которые на практике используют участники форума, а не канонические (описанные в msdn). Кстати лично я exception недолюбливаю.



--------------------
PM MAIL WWW   Вверх
bel_nikita
Дата 10.5.2004, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Эксперт
Сообщений: 2304
Регистрация: 12.10.2003
Где: Поезд №21/22 ( ст . Прага )

Репутация: 21
Всего: 47



AndyY
Что-тоя не въехал sad.gif , но есть GetLastError


--------------------
user posted image — регистрация доменов от 150 руб.
PM MAIL WWW ICQ   Вверх
mr.DUDA
Дата 10.5.2004, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



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


--------------------
user posted image
PM MAIL WWW   Вверх
Royan
Дата 10.5.2004, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Dreamer
***


Профиль
Группа: Участник Клуба
Сообщений: 1708
Регистрация: 14.9.2002
Где: Лондон

Репутация: нет
Всего: 15



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

AndyY, в ответ на твой вопрос, я вот например, написал пару-тройку функций для работы как с GetLastError, так и со всем остальным и заключил все в namespace, а после к ним можно обращаться откуда угодно, могу весь код положить сюда.

Это сообщение отредактировал(а) Royan - 10.5.2004, 19:50


--------------------
Открыта вакансия Junior Java Developer'а в нашем лондонском офисе, подробнее можно узнать здесь
PM MAIL MSN   Вверх
AndyY
Дата 10.5.2004, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



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


--------------------
PM MAIL WWW   Вверх
mr.DUDA
Дата 11.5.2004, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 25
Всего: 232



AndyY, как вариант - можно все функции, возвращающие NULL/не NULL в случае успеха или наоборот, заключать в макросы типа ASSERT, которые проверяют условие на истинность и вызывают исключение в случае неудачи. Пример (с отключаемыми в Release-версии проверками):
Цитата
class CMyException
{
public:
   
char err_msg[1000];
   
CMyException(const char *msg, int iLine, const char *file_name)
    {
       
sprintf(err_msg, "Ошибка в %d-ой строке файла %s. Текст выражения, вызвавшего ошибку: %s",
           
iLine, file_name, msg);
    }
};


#ifdef _DEBUG
   
#define MY_ASSERT(expr) {if(!(expr)) throw new CMyException(#expr, __LINE__, __FILE__);}
#else
    #define
MY_ASSERT(expr) expr
#endif


//////////////////////////////////////////////////////////////////////////
// тест

int main(int argc, char* argv[])
{
   
try
   
{
       
MY_ASSERT(true); // сработает
       
MY_ASSERT(false); // вызовет исключение
   
}
   
catch (CMyException *ex)
    {
       
printf(ex->err_msg);
       
delete ex;
    }

   
return 0;
}

В качестве практического примера можно заключить в MY_ASSERT вызов функций RegOpenKey, UnmapViewOfFile и пр. -- все они возвращают значение, по которому можно определить, выполнена ли операция успешно; проверив это значение макросом MY_ASSERT, можно выполнить некие действия при возникновении ошибки - закрыть файл, освободить память, выдать сообщение с информацией об ошибке из объекта CMyException *ex (это сообщение содержит номер строки, имя файла и выражение, вызвавшее ошибку -- вполне исчерпывающая информация).


--------------------
user posted image
PM MAIL WWW   Вверх
AndyY
Дата 11.5.2004, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 316
Регистрация: 8.5.2004
Где: СПб

Репутация: 2
Всего: 4



mr.DUDA спасибо, ваш метод понятен.

Значит, ваш код выглядит примерно так:

Код

HANDLE hfile = 0;
HANDLE hmap =0;
try{
MY_ASSERT(::RegOpenKey( ..., &hkey )!=0);
hfile = ::CreateFile( ... )
MY_ASSERT(hfile!=INVALID_HANDLE_VALUE);
...

}
catch( CMyException *pe )
{
...
pe->Delete();
}

if( hmap )::CloseHandle( hmap );
if( hfile )::CloseHandle( hfile );


Жду еще мнений.
Если интересно, свой взгляд на проблему я изложил тут


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1668 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.