Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/30: Рейтинг темы: голосов - 30, средняя оценка - 4.80
38 / 38 / 4
Регистрация: 03.09.2011
Сообщений: 279
1

Блок try-catch

30.12.2011, 00:40. Показов 5465. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение по адресу...". В чем может быть проблема?

Добавлено через 4 минуты
Протестил, проблема была в неполном блоке try. Вопрос, как знать каков должен быть блок, то есть, что туда должно входить?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.12.2011, 00:40
Ответы с готовыми решениями:

Не работает блок catch
Я создаю программу, которая выводит все решения задачи о 8 ферзях (если не знаете - погуглите, но...

Блок try-catch и ввод
Есть метод класса, который устанавливает дату в переменные типа int, я перелавливаю некоректный...

Блок try catch жрет память
Доброго времени суток! Проблема случилась там, где ее никак не ожидал, ответа ни в поисковиках, ни...

Работает ли указатель на базовый класс исключения, когда попадает в блок catch
Работает ли указатель на базовый класс исключения, когда попадает в блок catch так же как обычно?...

12
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
30.12.2011, 01:00 2
Цитата Сообщение от Vidok Посмотреть сообщение
В чем может быть проблема?
А понять по описании ошибки не пробовали? Не обработанное исключение - это значит, что исключение не обработали(Ваш КО).

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

Добавлено через 2 минуты
Читай как работают исключения и все ваши вопросы отпадут.
1
Эксперт С++
2347 / 1720 / 148
Регистрация: 06.03.2009
Сообщений: 3,675
30.12.2011, 01:06 3
Цитата Сообщение от Vidok Посмотреть сообщение
что туда должно входить?
Код, который может генерировать исключения.
0
32 / 15 / 1
Регистрация: 06.05.2011
Сообщений: 56
30.12.2011, 01:11 4
Блок кода, который требуется контролировать на проявление исключений, заключается в блок try. Если внутри этого блока возникает исключительная ситуация, то генерируется исключение. Это исключение может быть перехвачено и обработано кодом программы в блоке catch. Исключения, возникающие на уровне системы, генерируются исполняющей системой автоматически. Для генерирования исключений вручную используется слово throw.

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

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

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

Чтобы поймать исключения всех типов - catch(...){};
1
Заблокирован
Автор FAQ
30.12.2011, 10:47 5
Vidok, хотелось бы посмотреть конкретный код, а там бы и конкретный ответ созрел!
0
139 / 60 / 13
Регистрация: 04.09.2011
Сообщений: 1,956
Записей в блоге: 1
30.12.2011, 11:31 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.
Если исключение некритично, обрабатываем его и
возвращаемся в основной цикл. */ 
}
}
Заключение
Метод обработки исключений, приведенный в статье, является удобным и мощным средством, однако только вам решать, использовать его или нет. Одно можно сказать точно - приведенный метод облегчит вам жизнь.
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
30.12.2011, 11:54 7
Цитата Сообщение от Vidok Посмотреть сообщение
В некоторых программах он хорошо работает и в блоке catch выводит то что написал, а в некоторых среда VS говорит "Необработанное исключение по адресу...". В чем может быть проблема?
А ты понимаешь разницу между C++-исключениями и SEH-исключениями? Если нет, я рекомендовал бы к прочтению Джеффри Рихтера, "Windows для профессионалов" - там обработка исключений хорошо описана.
Книга есть в электронном виде в Сети, гугл в помощь.
0
38 / 38 / 4
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 15:15  [ТС] 8
Спасибо конечно что ответили, но здесь половина ответов это мануал который мне не нужен вообще, а некоторые как последний вообще ни к чему прилепили. Какая разница между такими то исключениями? Книгу читали по С++? Там обучают разнице между разными исключениями? Ну что за бред
1
Заблокирован
Автор FAQ
30.12.2011, 15:25 9
Vidok, выложи свой код!Я к чему веду - ты делаешь исключение к примеру для bad_alloc а у тебя деление ноль ещё в том блоке или что то в этом роде вот и получаешь
Цитата Сообщение от Vidok Посмотреть сообщение
а в некоторых среда VS говорит "Необработанное исключение по адресу..."

Не по теме:

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

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

Добавлено через 1 минуту
А то что вводил, передавалось в функцию как параметр
0
Эксперт С++
5043 / 2622 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
30.12.2011, 15:43 11
Цитата Сообщение от Vidok Посмотреть сообщение
насколько я понял, в блок try должно входить то, где генерируется исключение, у меня это было отдельно, я поместил в блок поток ввода, а функции сказал, если ввод меньше нужного то кинуть в catch, но саму функцию в блок не поместил, по этому была ошибка.
Цитата Сообщение от Vidok Посмотреть сообщение
Книгу читали по С++? Там обучают разнице между разными исключениями?
Да. А Вы?
0
38 / 38 / 4
Регистрация: 03.09.2011
Сообщений: 279
30.12.2011, 15:51  [ТС] 12
Читал, но автор дает код примера до того как будет говорить о исключениях и обработке ошибок. По этому и пишу сюда. Но сам понял больше, чем мне ответили в итоге
0
0 / 0 / 0
Регистрация: 22.04.2012
Сообщений: 11
05.06.2012, 15:41 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);
 
}
0
05.06.2012, 15:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.06.2012, 15:41
Помогаю со студенческими работами здесь

Как передать управление в блок catch после системного исключения (компилятор g++)?
Вот пример: не удаётся это сделать #include &lt;windows.h&gt; #include &lt;stdio.h&gt; ...

Один блок catch для двух типов исключений порожденных от одного класса
Товагищи!! Имеется задача с книги С. Прата с++11. Не могу реализовать следующее : Вот к чему...

Блок try и catch
В этой програме нужно сделать чтобы нельзя было вводить символы кроме цифр. И если k&gt;n выводить...

Блок try.catch
В одном из тестов наткнулся на такой код public static void main(String args) { ...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru