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

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

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

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

08.04.2010, 21:41. Просмотров 5257. Ответов 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; ...

41
Genius Ignat
1241 / 779 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
08.04.2010, 23:10 #16
ISergey:
То что вы процитировали не я придумал а более опытные программисты...

Работа с динамической памятью и указателями это работа сапера
нужно быть предельно аккуратным: соблюдать правила придуманные умными людьми,
а так же использовать опыт этих людей: изложенный в умных книгах.
0
CyBOSSeR
Эксперт С++
2307 / 1680 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
08.04.2010, 23:26 #17
Genius Ignat, ISergey прав, согласно стандарту в случае ошибки оператор new возбуждает исключение std::bad_alloc. В связи с эти проверка на NULL не уместна.
1
paramonies
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10
09.04.2010, 00:20  [ТС] #18
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Может быть от того что оператор new принимает аргумент типа size_t, он же unsigned int?
Почему же тогда во втором случае исключение bad_alloc обработать не удается?
0
CyBOSSeR
Эксперт С++
2307 / 1680 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 00:31 #19
paramonies, видимо потому что у тебя достаточно памяти и она успешно выделяется.
Попробуй такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
char* p;
       try
       {   for(int i = 0; i < 1000; i++)
            {   p = new char[-1];
                cout <<  i << ":success of allocation " << endl;
            }
        }
        catch(bad_alloc)
        {    cout <<  "Allocation failure " << endl;
              abort();
        }
На одной из итераций вылетишь с исключением.
0
Genius Ignat
1241 / 779 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
09.04.2010, 11:54 #20
Не большой итог, который я подвел для себя.

По мне так лучше не исключение а NULL обрабатывать.
Только этот способ по умолчанию имеет две запарки, для моего примера надо написать
оболочку new и тогда всё гарантированно будет срабатывать, а пример ISergey показывает что
везде надо прописывать nothrow, как то тоже геморрой.

И собственно небольшой вопрос есть ли new по умолчанию возвращающая NULL?
старая добрая malloc возвращает же значение о неудачном выделении,
и ни каких try catch.

Может исключения и дают какие то преимущества, допустим для конструкторов и других
конструкций не имеющих возврат знач, для меня исключения просто портят читаемость.

Добавлено через 33 минуты
Странно при обработке new хоть на NULL хоть try catch, встает вопрос и что делать в обработке,
то ли закрыть программу все равно не правильно работает, либо попробовать еще раз new
,а если еще раз не удачно опять обработка(бесконечность),
вообще без выделенной памяти я не вижу вообще смысла продолжать работать
(всё равно вывалится ошибка runtime),
или что на каждом исключении или NULL я должен
разрабатывать план действий (B), который тоже ни к чему не приведет,
так как за одной ошибкой может быть другая ошибка.

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

Да и тем более зачем клиенту информировать при ошибке в конструкторе,
когда ошибка не от тебя зависит и не ты её сделал,
даже информативность обработки в клиенте не поможет, допустим и что толку макросы assert
точка в клиенте где произошла ошибка выделения памяти, тоже не чего не даст.

Извините что не в тему но данным вопрос мне интересен.
Что вообще делать если память не выделилась?
Плакать или что?

Добавлено через 11 минут
Genius Ignat, ISergey прав, согласно стандарту в случае ошибки оператор new возбуждает исключение std::bad_alloc. В связи с эти проверка на NULL не уместна.
Все законно, если не будет обработки исключения и не будет возврата какой нибудь как...шки
из new, тогда указатель инициализированный NULL после new всё равно будет NULL,
ещё раз говорю не я это придумал, приводить код microsoft не буду, все равно одно и тоже.

Добавлено через 6 минут
не буду, все равно одно и тоже.
А если хотите могу привести, если вы сомневаетесь в компетентности microsoft.
1
Patch
2277 / 492 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
09.04.2010, 12:14 #21
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Что вообще делать если память не выделилась?
в хорошей программе должны быть разные алгоритмы, способные работать с разными объемами памяти.
если памяти много - работает один, если мало - другой.
чаще всего, значительная часть выделенной памяти вообще не используется, или используется крайне редко.
на этом и построен обычный страничный обмен Windows с файлами подкачки.
хорошо спроектированная программа тоже может делать подобное - например, использовать временные файлы.

т.е., при возникновении исключения по нехватке памяти, обработчик исключения выгружает ненужные в текущий момент данные в файл, освобождает память, и продолжает работу.
1
CyBOSSeR
Эксперт С++
2307 / 1680 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 14:20 #22
Цитата Сообщение от Genius Ignat Посмотреть сообщение
Может исключения и дают какие то преимущества, допустим для конструкторов и других
конструкций не имеющих возврат знач, для меня исключения просто портят читаемость.
Genius Ignat, ни в коем случае нельзя возбуждать исключения в конструкторе. Проблем не оберешься.
1
Genius Ignat
1241 / 779 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
09.04.2010, 15:46 #23
Может кто объяснить у меня на 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
Эксперт С++
2307 / 1680 / 86
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 15:57 #24
Genius Ignat, скорее всего дело в IDE или ее настройках. MSVS 2005/2008 ведет себя согласно стандарту - кидает std::bad_alloc.
1
Genius Ignat
1241 / 779 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
09.04.2010, 16:05 #25
Ну мягкомалые дают то так:
int *p = NULL;
delete p; //ошибочка
у них в VC++ 6.0, то new возвращает NULL по умолчанию.

Провел ещё тест в VS2008 на bad_alloc реагирует и если передашь nothrow тоже.
Короче говоря это проблемы microsoft, жаль эту фичу не перенести на VS2008.
0
Patch
2277 / 492 / 11
Регистрация: 01.04.2009
Сообщений: 2,178
09.04.2010, 16:33 #26
меня вообще удивляет, как это вы вызываете векторный оператор new для выделения массива под скалярные переменные.
а потом еще и пытаетесь их удалить.
когда я пытался так сделать несколько лет назад, у меня программа очень стабильно вываливалась с ошибкой.
0
Genius Ignat
1241 / 779 / 44
Регистрация: 16.09.2009
Сообщений: 2,014
09.04.2010, 16:38 #27
Прочитал:
http://ru.wikipedia.org/wiki/New_(C%2B%2B)
и это про заморочки с VC++ 6.0:
http://forum.ixbt.com/topic.cgi?id=26:15791
И понял что ввел себя в заблуждение надеюсь только себя, а если еще кого тогда извиняюсь.
Надо завязывать со старым компилятором иначе к новому ни когда не привыкну.

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

Не по теме:


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

0
ISergey
09.04.2010, 19:53     Обработка исключений для new
  #30

Не по теме:

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

Не по теме:


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

скоро..

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
30
09.04.2010, 19:53
Ответ Создать тему
Опции темы

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