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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 34, средняя оценка - 4.82
paramonies
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10
#1

Обработка исключений для new - C++

08.04.2010, 21:41. Просмотров 4815. Ответов 41
Метки нет (Все метки)

Всем привет!
Вопрос следующий. Когда функция new не может выделить память, то генериться исключение bad_alloc.
Допустим есть следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
     
       char* p;
       try
       {   for(int i = 0; i < 20; i++)
        {   p = new char[614400000U];
        cout <<  i << ":success of allocation " << endl;
        }
    }
    catch(bad_alloc)
    {    cout <<  "Allocation failure " << endl;
          abort();
    }
На каком то i шаге память закончится, сгенериться bad_alloc и мы попадем в блок catch()
А вот другой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
     
       char* p;
       try
       {   for(int i = 5; i > -5; i--)
        {   p = new char[i];
        cout <<  i << ":success of allocation " << endl;
        }
    }
    catch(bad_alloc)
    {    cout <<  "Allocation failure " << endl;
          abort();
    }
При отрицательном i, никакой обработки исключения не происходит, программа вываливается.
Вопрос: как в этом случае ведет себя new и как попасть в блок catch()?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.04.2010, 21:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обработка исключений для new (C++):

Обработка исключений с пмощью структурированной обработки исключений - C++
Есть функция, которая определенным образом работает с файлами,но при работе с файлами &quot;не подходящего&quot; типа вызывается необработанное...

Обработка исключений в классах для пользовательских типов - C++
Здорова господа! Запустил токо класс String тестю и тут у меня вылетело исключение выход за пределы индекса, и программа тупо аварийно...

обработка исключений - C++
Есть вот такой код: #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; int _tmain(int argc, _TCHAR* argv) { ...

Обработка исключений - C++
Объясните мне толком для чего используются эти обработки исключений (Try, catch, throw). Сколько не читаю, не могу понять для чего и как...

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

Обработка исключений - C++
Почему не перехватывает ошибку и не выводит Error? а прога сама прекращает работу. #include &lt;iostream&gt; using namespace std; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
09.04.2010, 23:12 #31
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Genius Ignat, ни в коем случае нельзя возбуждать исключения в конструкторе. Проблем не оберешься.
Не согласен. Это единственный способ сообщить об ошибке в конструкторе. Иначе - что вообще делать, если в конструкторе не удалось по тем или иным причинам создать "работоспособный" объект? Это ведь относится не только к выделению памяти, но и к другим ресурсам......
А вот нельзя возбуждать исключения - в деструкторе.
2
CyBOSSeR
Эксперт C++
2302 / 1672 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 23:54 #32
CheshireCat, хорошо, я слишком категорически выразился.
Возбуждение исключений в конструкторе при возможности стоит избегать. Проблема в том, что если объект создается динамически и в конструкторе возникнет исключение, то деструктор вызван не будет. В связи с этим нужно очень аккуратно следить за процессом конструирования, чтобы суметь откатится назад.
1
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
10.04.2010, 10:44 #33
Хорошо, поправка насчет излишней категоричности принята :-)
А вот в остальном - тоже не вполне верно. Да, если в конструкторе выброшено исключение, то деструктор вызван никогда не будет - объект еще никогда не "жил". Однако, Стандарт языка гарантирует нам, что для всех уже полностью сконструированных до этого момента подъобъектов (баз и членов) будут вызваны их деструкторы. Так что вручную следить за корректным "откатом назад" не стоит - если, конечно, сами конструкторы/деструкторы баз и членов выполнены правильно.
1
Genius Ignat
1236 / 774 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
10.04.2010, 12:27 #34
Раскрою одну страшную тайную которая не является тайной, недавно узнал что
в конструкторе можно делать return; а ещё есть механизм обработки ошибки в конструкторе
без исключения, это я узнал из COM вероятно стандартом исключения там не разрешены.


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
31
32
33
34
35
36
#include <iostream.h>
#include <objbase.h>
 
class MyClass {
public:
MyClass(int a, int b , HRESULT *hr);
};
 
MyClass::MyClass(int a, int b , HRESULT *hr){
    
if(b==0){
    *hr=E_FAIL;
         return;
    }
 
int c = a/b;
*hr = S_OK;
}
 
 
int main(){
 
HRESULT hr ;
MyClass obj1(2,0,&hr);
 
if(SUCCEEDED(hr))cout<<"Ok\n";
if(FAILED(hr)) cout<<"Division on 0\n";
 
MyClass obj2(2,2,&hr);
 
if(SUCCEEDED(hr))cout<<"Ok\n";
if(FAILED(hr)) cout<<"Division on 0\n";
 
 
return 0;
}
Замысел прост, можно было и без COM, смысл такой передаём выходной параметр,
и проверяем его значение на удачность.
Раньше я не задумывался: что возвращаемое значение еще можно получать через параметры.
Может кому интересен этот способ.

Добавлено через 11 минут
Как быть с конструктором копирования и операцией присваивания это надо подумать.

Добавлено через 3 минуты
Одно есть преимущество при такой передаче юзер обязан передать hr это и радует.
А от возвращаемого значения можно отказаться допустим при вызове простой функции.

Добавлено через 6 минут
А кто хочет обрабатывать(bad_alloc) new в конструкторе
предусмотрено такое для hr значение: E_OUTOFMEMORY;
0
CyBOSSeR
Эксперт C++
2302 / 1672 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 12:45 #35
CheshireCat, да, но если в конструкторе некие объекты создаются динамически, то при исключении они уничтожены не будут. Поэтому нужно либо следить (чтобы не забыть удалить), какие объекты к моменту исключения были созданы динамически, либо использовать некие обертки над такими объектами, которые сами в случае чего их удалят.
0
Genius Ignat
1236 / 774 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
10.04.2010, 13:21 #36
Языки не совершенны и где нибудь да найдется не удобная запарка.
CyBOSSeR:
Может все проще: ждем сборщик мусора, а пока терпим неудобства.
Судя по VC++ 6.0, если сборщик мусора будет в новом стандарте C++,
в компиляторах он появится с опозданием и недоделками.
0
rangerx
10.04.2010, 13:27
  #37

Не по теме:

Цитата Сообщение от Genius Ignat Посмотреть сообщение
Когда выйдет новый стандарт по C++ или он уже вышел?
Обещают в следующем году

1
CyBOSSeR
Эксперт C++
2302 / 1672 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 13:40 #38
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Может все проще: ждем сборщик мусора, а пока терпим неудобства
Зачем нужна сборка мусора для C++, даже если ее поведение будет строго детерминировано?
Не вижу в ней смысла никакого вообще.
0
Genius Ignat
1236 / 774 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
10.04.2010, 14:12 #39
Зачем нужна сборка мусора для C++, даже если ее поведение будет строго детерминировано
Читал знаемс.

Добавлено через 20 минут
CheshireCat, да, но если в конструкторе некие объекты создаются динамически, то при исключении они уничтожены не будут. Поэтому нужно либо следить (чтобы не забыть удалить), какие объекты к моменту исключения были созданы динамически, либо использовать некие обертки над такими объектами, которые сами в случае чего их удалят.
Представил картинку которая будет вокруг каждого new в конструкторе try catch catch try
что просто по мне так то что сказал CyBOSSeR проще, реализовать new с параметром nothrow.
Так как при nothrow понятно создан объект значит !NULL.

А без nothrow мне видится картина с массивом указателей хранящих NULL
а если объект создан в массив заносится адрес созданного объекта.
А если возникнет исключение, с помощью массива можно зачистить все не NULL.

Добавлено через 57 секунд
Думаю я размышляю в правильную сторону.
0
CyBOSSeR
Эксперт C++
2302 / 1672 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 14:19 #40
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Думаю я размышляю в правильную сторону.
CheshireCat прав в случае невозможности создать работоспособный объект, конструктор должен выкинуть исключение, просто нужно аккуратно следить за объектами, которые конструктор создает динамически, либо использовать для них обертки.
1
CheshireCat
Эксперт С++
2892 / 1241 / 78
Регистрация: 27.05.2008
Сообщений: 3,370
10.04.2010, 22:52 #41
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
CheshireCat прав в случае невозможности создать работоспособный объект, конструктор должен выкинуть исключение, просто нужно аккуратно следить за объектами, которые конструктор создает динамически, либо использовать для них обертки.
А техника такого действия очень несложна; она хорошо описана у уважаемого Херба Саттера в его "Решение сложных задач на C++" и "Новые сложные задачи на C++".
2
CyBOSSeR
10.04.2010, 23:04     Обработка исключений для new
  #42

Не по теме:

CheshireCat, спасибо за упоминание литературы.

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.04.2010, 23:04
Привет! Вот еще темы с ответами:

Обработка исключений - C++
класс B является производным от абстрактного класса А. Определить обработчик исключительной ситуации при преобразовании указателя на класс...

Обработка исключений - C++
Надо отловить ввод данных некорректного типа. Объясните пожалуйста на конкретном примере, как это правильно сделать. #include...

Обработка исключений - C++
Помогите написать программу пожалуйста!!!! Я незнаю как правильно написать!!! Задание: Для каждого варианта необходимо создать три...

Обработка исключений - C++
что то я не пойму а что в плюсах нельзя разве сделать что то типа: try { ... } catch (int) { ... }


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
10.04.2010, 23:04
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru