Форум программистов, компьютерный форум CyberForum.ru

Блок try-catch - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.59
Vidok
 Аватар для Vidok
36 / 36 / 2
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 00:40     Блок try-catch #1
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение по адресу...". В чем может быть проблема?

Добавлено через 4 минуты
Протестил, проблема была в неполном блоке try. Вопрос, как знать каков должен быть блок, то есть, что туда должно входить?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.12.2011, 00:40     Блок try-catch
Посмотрите здесь:

try catch C++
C++ try-catch
Как передать управление в блок catch после системного исключения (компилятор g++)? C++
C++ TRY/CATCH
C++ try . catch
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
30.12.2011, 01:00     Блок try-catch #2
Цитата Сообщение от Vidok Посмотреть сообщение
В чем может быть проблема?
А понять по описании ошибки не пробовали? Не обработанное исключение - это значит, что исключение не обработали(Ваш КО).

Цитата Сообщение от Vidok Посмотреть сообщение
Протестил, проблема была в неполном блоке try. Вопрос, как знать каков должен быть блок, то есть, что туда должно входить?
В блок try может входить все что угодно.

Добавлено через 2 минуты
Читай как работают исключения и все ваши вопросы отпадут.
CyBOSSeR
Эксперт C++
 Аватар для CyBOSSeR
2293 / 1663 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
30.12.2011, 01:06     Блок try-catch #3
Цитата Сообщение от Vidok Посмотреть сообщение
что туда должно входить?
Код, который может генерировать исключения.
DimonR91
13 / 13 / 1
Регистрация: 06.05.2011
Сообщений: 56
30.12.2011, 01:11     Блок try-catch #4
Блок кода, который требуется контролировать на проявление исключений, заключается в блок try. Если внутри этого блока возникает исключительная ситуация, то генерируется исключение. Это исключение может быть перехвачено и обработано кодом программы в блоке catch. Исключения, возникающие на уровне системы, генерируются исполняющей системой автоматически. Для генерирования исключений вручную используется слово throw.

Если отсутствует catch с типом исключения, которое возникло, то также вы не словите это исключение.

Однако если у вас есть catch с типом, который является базовым типом для возникшего исключения, то этот блок catch поймает и его.

То есть, у нас вызвано исключение типа MyException, который является производным от Exception.
То исключение типа MyException будет перехвачено в блоке catch(Exception).

Чтобы поймать исключения всех типов - catch(...){};
-=ЮрА=-
Заблокирован
Автор FAQ
30.12.2011, 10:47     Блок try-catch #5
Vidok, хотелось бы посмотреть конкретный код, а там бы и конкретный ответ созрел!
Sylar9
-20 / 55 / 2
Регистрация: 04.09.2011
Сообщений: 1,888
Записей в блоге: 1
30.12.2011, 11:31     Блок try-catch #6
Цитата Сообщение от Vidok Посмотреть сообщение
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение по адресу...". В чем может быть проблема?

Добавлено через 4 минуты
Протестил, проблема была в неполном блоке try. Вопрос, как знать каков должен быть блок, то есть, что туда должно входить?
Язык С представляет программисту очень ограниченные возможности обработки исключений, возникших при работе программы. В этом отношении С++ намного развитее С. Здесь у программиста существенно большие возможности по непосредственной обработке исключений. Комитет по разработке стандартов С++ предоставил очень простую, но мощную форму обработки исключений.
Темные дни С

Типичная функция, написанная на С, выглядит примерно так:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
long DoSomething()
{
long *a, c;
FILE *b;
a = malloc(sizeof(long) * 10);
if (a == NULL)
return 1;
b = fopen("something.bah", "rb");
if (b == NULL) {
free(a);
return 2;
}
fread(a, sizeof(long), 10, b);
if (a[0] != 0x10) {
free(a);
fclose(b);
return 3;
}
fclose(b);
c = a[1];
free(a);
return c;
}
Выглядит не очень, не так ли? Вы целиком и полностью зависите от значений, которые возвращают вам функции и для каждой ошибки вам постоянно нужен код, который ее обрабатывает. Если вы, скажем, в функции работаете хотя бы с 10 указателями (рапределяете память, освобождаете ее и т.д.), то наверняка половину кода функции будет занимать код обработки ошибок. Такая же ситуация будет в коде, вызывающем эту функцию, так как здесь также нужно обработать все возвращаемые коды ошибок.

Try-catch-throw

Давайте же разберем основы обработки исключений в С++. Чтобы комфортно работать с исключениями в С++ вам нужно знать лишь три ключевых слова:
  • try (пытаться) - начало блока исключений;
  • catch (поймать) - начало блока, "ловящего" исключение;
  • throw (бросить) - ключевое слово, "создающее" ("возбуждающее") исключение.

А теперь пример, демонстрирующий, как применить то, что вы узнали:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void func()
{
try
{
throw 1;
}
catch(int a)
{
cout << "Caught exception number: " << a << endl;
return;
}
cout << "No exception detected!" << endl;
return;
}
Если выполнить этот фрагмент кода, то мы получим следующий результат:
Код
Caught exception number: 1
Теперь закоментируйте строку throw 1; и функция выдаст такой результат:
Код
No exception detected!
Как видите все очень просто, но если это применить с умом, такой подход покажется вам очень мощным средством обработки ошибок. Catch может "ловить" любой тип данных, так же как и throw может "кинуть" данные любого типа. Т.е. throw AnyClass(); будет правильно работать, так же как и catch (AnyClass &d) {};.

Как уже было сказано, catch может "ловить" данные любого типа, но вовсе не обязательно при это указывать переменную. Т.е. прекрасно будет работать что-нибудь типа этого:
C++
1
catch(dumbclass) { }
так же, как и
C++
1
catch(dumbclass& ) { }
Так же можно "поймать" и все исключения:
C++
1
catch(...) { }
Троеточие в этом случае показывает, что будут пойманы все исключения. При таком подходе нельзя указать имя переменной. В случае, если "кидаются" данные нестандартного типа (экземпляры определенных вами классов, структур и т.д.), лучше "ловить" их по ссылке, иначе вся "кидаемая" переменная будет скопирована в стек вместо того, чтобы просто передать указатель на нее. Если кидаются данные нескольких типов и вы хотите поймать конкретную переменную (вернее, переменную конкретного типа), то можно использовать несколько блоков catch, ловящих "свой" тип данных:
C++
1
2
3
4
5
6
7
8
9
10
try {
throw 1;
// throw 'a';
}
catch (long b) {
cout << "пойман тип long: " << b << endl;
}
catch (char b) {
cout << "пойман тип char: " << b << endl;
}
"Создание" исключений

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

Однако более важным моментом является то, что пока просматривается стек функций, вызываются деструкторы всех локальных классов, так что вам не нужно забодиться об освобождении памяти и т.п.

Перегрузка глобальных операторов new/delete

А сейчас хотелось бы отправить вас к статье "Как обнаружить утечку памяти". В ней рассказывается, как обнаружить неправильное управление распределением памяти в вашей программе. Вы можете спросить, при чем тут перегрузка операторов? Если перегрузить стандартные new и delete, то открываются широкие возможности по отслеживанию ошибок (причем ошибок часто критических) с помощью исключений. Например:
C++
1
2
3
4
5
6
7
8
9
10
char *a;
try
{
a = new char[10];
}
catch (...){
// a не создан - обработать ошибку распределения памяти, 
// выйти из программы и т.п.
}
// a успешно создан, продолжаем выполнение
Это, на первый взгляд, кажется длиннее, чем стандартная проверка в С "а равен NULL?", однако если в программе выделяется десяток динамических переменных, то такой метод оправдывает себя.
Операторы throw без параметров

Итак, мы увидели, как новый метод обработки ошибок удобен и прост. Блок try-catch может содержать вложенные блоки try-catch и если не будет определено соответствующего оператора catch на текущем уровен вложения, исключение будет поймано на более высоком уровне. Единственная вещь, о которой вы должны помнить, - это то, что операторы, следующие за throw, никогда не выполнятся.
C++
1
2
3
4
5
6
7
8
9
10
try
{
throw;
// ни один оператор, следующий далее (до закрывающей скобки) 
// выполнен не будет
}
catch(...)
{
cout << "Исключение!" << endl;
}
Такой метод может применяться в случаях, когда не нужно передавать никаких данных в блок catch.
Приложение

Приведем пример, как все вышеизложенное может быть использовано в конкретном приложении. Преположим, у вас в программе есть класс cMain и экземпляр этого класса Main:
C++
1
class cMain { public: bool Setup(); bool Loop(); // Основной цикл программы void Close(); }; cMain Main;
А в функции main() или WinMain() вы можете использовать этот класс как-нибудь так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
try
{
Main.Setup();
Main.Loop();
Main.Close();
}
catch (Exception &e)
{
// использование класса, ведущего лог.
log("Exception thrown: %s", e.String()); 
 
// Показываем сообщение об ошибке и закрываем приложение.
}
 
Основной цикл программы может выглядеть примерно так: 
while (AppActive)
{
try
{
// какие-то действия
}
catch (Exception &e)
{
/* Если исключение критическое, типа ошибки памяти,
посылаем исключение дальше, в main(), оператором throw e;
или просто throw.
Если исключение некритично, обрабатываем его и
возвращаемся в основной цикл. */ 
}
}
Заключение
Метод обработки исключений, приведенный в статье, является удобным и мощным средством, однако только вам решать, использовать его или нет. Одно можно сказать точно - приведенный метод облегчит вам жизнь.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
30.12.2011, 11:54     Блок try-catch #7
Цитата Сообщение от Vidok Посмотреть сообщение
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение по адресу...". В чем может быть проблема?
А ты понимаешь разницу между C++-исключениями и SEH-исключениями? Если нет, я рекомендовал бы к прочтению Джеффри Рихтера, "Windows для профессионалов" - там обработка исключений хорошо описана.
Книга есть в электронном виде в Сети, гугл в помощь.
Vidok
 Аватар для Vidok
36 / 36 / 2
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 15:15  [ТС]     Блок try-catch #8
Спасибо конечно что ответили, но здесь половина ответов это мануал который мне не нужен вообще, а некоторые как последний вообще ни к чему прилепили. Какая разница между такими то исключениями? Книгу читали по С++? Там обучают разнице между разными исключениями? Ну что за бред
-=ЮрА=-
Заблокирован
Автор FAQ
30.12.2011, 15:25     Блок try-catch #9
Vidok, выложи свой код!Я к чему веду - ты делаешь исключение к примеру для bad_alloc а у тебя деление ноль ещё в том блоке или что то в этом роде вот и получаешь
Цитата Сообщение от Vidok Посмотреть сообщение
а в некоторых среда VS говорит "Необработанное исключение по адресу..."

Не по теме:

Ну понятно что ты кодишь и в чём то разбираешся и т.д., но неужели код сложно поцепить???

Vidok
 Аватар для Vidok
36 / 36 / 2
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 15:32  [ТС]     Блок try-catch #10
Так с кодом я уже разобрался) насколько я понял, в блок try должно входить то, где генерируется исключение, у меня это было отдельно, я поместил в блок поток ввода, а функции сказал, если ввод меньше нужного то кинуть в catch, но саму функцию в блок не поместил, по этому была ошибка.

Добавлено через 1 минуту
А то что вводил, передавалось в функцию как параметр
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
30.12.2011, 15:43     Блок try-catch #11
Цитата Сообщение от Vidok Посмотреть сообщение
насколько я понял, в блок try должно входить то, где генерируется исключение, у меня это было отдельно, я поместил в блок поток ввода, а функции сказал, если ввод меньше нужного то кинуть в catch, но саму функцию в блок не поместил, по этому была ошибка.
Цитата Сообщение от Vidok Посмотреть сообщение
Книгу читали по С++? Там обучают разнице между разными исключениями?
Да. А Вы?
Vidok
 Аватар для Vidok
36 / 36 / 2
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 15:51  [ТС]     Блок try-catch #12
Читал, но автор дает код примера до того как будет говорить о исключениях и обработке ошибок. По этому и пишу сюда. Но сам понял больше, чем мне ответили в итоге
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.06.2012, 15:41     Блок try-catch
Еще ссылки по теме:

C++ Блок try catch жрет память
Работает ли указатель на базовый класс исключения, когда попадает в блок catch C++
C++ Один блок catch для двух типов исключений порожденных от одного класса

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Alejandro
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 11
05.06.2012, 15:41     Блок try-catch #13
Привет!
Выдает системную ошибку и все тут
Как поймать подскажите, пожалуйста!
C++
1
2
3
4
5
6
7
8
9
try
{
r = StrToInt(Edit15->Text);
}
catch (Exception *ex)
{
Application->MessageBox(ex->Message.c_str(), "Error!!!", MB_OK | MB_ICONSTOP);
 
}
Yandex
Объявления
05.06.2012, 15:41     Блок try-catch
Ответ Создать тему
Опции темы

Текущее время: 17:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru