Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/79: Рейтинг темы: голосов - 79, средняя оценка - 4.54
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10

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

08.04.2010, 21:41. Показов 17252. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
08.04.2010, 21:41
Ответы с готовыми решениями:

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

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

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

41
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
09.04.2010, 12:14
Лучший ответ Сообщение было отмечено как решение

Решение

Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Что вообще делать если память не выделилась?
в хорошей программе должны быть разные алгоритмы, способные работать с разными объемами памяти.
если памяти много - работает один, если мало - другой.
чаще всего, значительная часть выделенной памяти вообще не используется, или используется крайне редко.
на этом и построен обычный страничный обмен Windows с файлами подкачки.
хорошо спроектированная программа тоже может делать подобное - например, использовать временные файлы.

т.е., при возникновении исключения по нехватке памяти, обработчик исключения выгружает ненужные в текущий момент данные в файл, освобождает память, и продолжает работу.
1
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 14:20
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Может исключения и дают какие то преимущества, допустим для конструкторов и других
конструкций не имеющих возврат знач, для меня исключения просто портят читаемость.
Genius Ignat, ни в коем случае нельзя возбуждать исключения в конструкторе. Проблем не оберешься.
1
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
09.04.2010, 15:46
Может кто объяснить у меня на VC++ 6.0 new вернула NULL без всяких примочек,
может я что то не до понимаю или это компилятор старый или что?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream.h>
int main()
{
     char* p;
       
           for(int i = 0; p!=NULL ; i++)
           {
              
                p = new char[1000000];
                cout <<  i << ":success of allocation\n";
           }
if(p==NULL)cout<<"error\n";
int a ; cin>>a;  //что бы консоль не вылетала.
return 0;
}
Добавлено через 36 секунд
Щас проверю на VS 2008

Добавлено через 4 минуты

Не по теме:


на Visual Studio нормально не проверил, вылетела ошибка библиотека USER32.dll перемещена в памяти,



Добавлено через 10 минут
Если кто знает как проверить эту особенность в Visual Studio 2008
пожалуйста отпишитесь, есть ли это в VS 2008.
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 15:57
Genius Ignat, скорее всего дело в IDE или ее настройках. MSVS 2005/2008 ведет себя согласно стандарту - кидает std::bad_alloc.
1
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
09.04.2010, 16:05
Ну мягкомалые дают то так:
int *p = NULL;
delete p; //ошибочка
у них в VC++ 6.0, то new возвращает NULL по умолчанию.

Провел ещё тест в VS2008 на bad_alloc реагирует и если передашь nothrow тоже.
Короче говоря это проблемы microsoft, жаль эту фичу не перенести на VS2008.
0
2343 / 499 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
09.04.2010, 16:33
меня вообще удивляет, как это вы вызываете векторный оператор new для выделения массива под скалярные переменные.
а потом еще и пытаетесь их удалить.
когда я пытался так сделать несколько лет назад, у меня программа очень стабильно вываливалась с ошибкой.
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
09.04.2010, 16:38
Прочитал:
http://ru.wikipedia.org/wiki/New_(C%2B%2B)
и это про заморочки с VC++ 6.0:
http://forum.ixbt.com/topic.cgi?id=26:15791
И понял что ввел себя в заблуждение надеюсь только себя, а если еще кого тогда извиняюсь.
Надо завязывать со старым компилятором иначе к новому ни когда не привыкну.

Добавлено через 2 минуты
За ссылку на форум извинюсь.
1
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 16:41
Genius Ignat, в случае неоднозначности заглядывай в стандарт. Все таки именно он должен быть первоисточником, а не документация производителя компилятора.
1
09.04.2010, 16:45

Не по теме:


Когда выйдет новый стандарт по C++ или он уже вышел?

0
09.04.2010, 19:53

Не по теме:

Цитата Сообщение от Genius Ignat Посмотреть сообщение

Не по теме:


Когда выйдет новый стандарт по C++ или он уже вышел?

скоро.. :)

0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
09.04.2010, 23:12
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Genius Ignat, ни в коем случае нельзя возбуждать исключения в конструкторе. Проблем не оберешься.
Не согласен. Это единственный способ сообщить об ошибке в конструкторе. Иначе - что вообще делать, если в конструкторе не удалось по тем или иным причинам создать "работоспособный" объект? Это ведь относится не только к выделению памяти, но и к другим ресурсам......
А вот нельзя возбуждать исключения - в деструкторе.
2
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 23:54
CheshireCat, хорошо, я слишком категорически выразился.
Возбуждение исключений в конструкторе при возможности стоит избегать. Проблема в том, что если объект создается динамически и в конструкторе возникнет исключение, то деструктор вызван не будет. В связи с этим нужно очень аккуратно следить за процессом конструирования, чтобы суметь откатится назад.
1
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
10.04.2010, 10:44
Хорошо, поправка насчет излишней категоричности принята :-)
А вот в остальном - тоже не вполне верно. Да, если в конструкторе выброшено исключение, то деструктор вызван никогда не будет - объект еще никогда не "жил". Однако, Стандарт языка гарантирует нам, что для всех уже полностью сконструированных до этого момента подъобъектов (баз и членов) будут вызваны их деструкторы. Так что вручную следить за корректным "откатом назад" не стоит - если, конечно, сами конструкторы/деструкторы баз и членов выполнены правильно.
1
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
10.04.2010, 12:27
Раскрою одну страшную тайную которая не является тайной, недавно узнал что
в конструкторе можно делать 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
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 12:45
CheshireCat, да, но если в конструкторе некие объекты создаются динамически, то при исключении они уничтожены не будут. Поэтому нужно либо следить (чтобы не забыть удалить), какие объекты к моменту исключения были созданы динамически, либо использовать некие обертки над такими объектами, которые сами в случае чего их удалят.
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
10.04.2010, 13:21
Языки не совершенны и где нибудь да найдется не удобная запарка.
CyBOSSeR:
Может все проще: ждем сборщик мусора, а пока терпим неудобства.
Судя по VC++ 6.0, если сборщик мусора будет в новом стандарте C++,
в компиляторах он появится с опозданием и недоделками.
0
10.04.2010, 13:27

Не по теме:

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

1
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 13:40
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Может все проще: ждем сборщик мусора, а пока терпим неудобства
Зачем нужна сборка мусора для C++, даже если ее поведение будет строго детерминировано?
Не вижу в ней смысла никакого вообще.
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
10.04.2010, 14:12
Зачем нужна сборка мусора для C++, даже если ее поведение будет строго детерминировано
Читал знаемс.

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

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

Добавлено через 57 секунд
Думаю я размышляю в правильную сторону.
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
10.04.2010, 14:19
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Думаю я размышляю в правильную сторону.
CheshireCat прав в случае невозможности создать работоспособный объект, конструктор должен выкинуть исключение, просто нужно аккуратно следить за объектами, которые конструктор создает динамически, либо использовать для них обертки.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.04.2010, 14:19
Помогаю со студенческими работами здесь

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

обработка исключений
Здравствуйте. В следующем коде, при запуске throw выдает ошибку &quot;Exception object adress&quot;. Не понимаю почему. Подскажите пожалуйста. ...

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

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

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


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru