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

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

08.04.2010, 21:41. Показов 17122. Ответов 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
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 21:52
У меня срабатывает исключение такое же как и при положительном счетчике

Добавлено через 41 секунду
Code
1
2
3
4
0:success of allocation
1:success of allocation
2:success of allocation
Allocation failure
Code
1
2
3
4
0:success of allocation
-1:success of allocation
-2:success of allocation
Allocation failure
0
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10
08.04.2010, 22:15  [ТС]
каким чудесным образом?)
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 22:17
Цитата Сообщение от paramonies Посмотреть сообщение
каким чудесным образом?)
Я бы задал этот же вопрос, только наоборот)) каким чудесным образом она не работает у тебя? ))))..
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
08.04.2010, 22:21
Если соблюдать правила хорошего тона можно обойтись и без исключений пример:
C++
1
2
3
4
5
6
7
int main(){
int *p = NULL;
p = new int(0);
if(p==NULL)return -1;
else delete p;
return 0;
}
Добавлено через 42 секунды

Не по теме:


Если бы все его соблюдали...

0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 22:23
Вопрос то, как я понял не в обработке ошибок при выделении памяти, а именно в отрицательном счетчике
0
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10
08.04.2010, 22:24  [ТС]
Ну просто по твоему результату видно, что new два раза выделил память под массивы с отрицательным числом элементов, почему не выделил третий раз, почему выскочило исключение тогда?
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 22:26
Цитата Сообщение от paramonies Посмотреть сообщение
почему не выделил третий раз, почему выскочило исключение тогда?
Память не резиновая, после каждого вызова new необходимо делать вызов delete
C++
1
delete[] p;
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
08.04.2010, 22:29
А вы не думаете, что дело в том, что отрицательное int неявно преобразуется в unsigned int, что дает очень большое число?
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 22:32
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
А вы не думаете, что дело в том, что отрицательное int неявно преобразуется в unsigned int, что дает очень большое число?
А с чего бы ему преобразовываться?
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
08.04.2010, 22:38
Цитата Сообщение от fasked Посмотреть сообщение
А с чего бы ему преобразовываться?
Может быть от того что оператор new принимает аргумент типа size_t, он же unsigned int?
1
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
08.04.2010, 22:40
C++
1
2
3
4
5
6
7
8
9
10
11
 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();
        }
Исключение генерируются когда происходит не хватка памяти, а не правильный
индекс для задания размера массива это извините кривые руки программиста.
1
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
08.04.2010, 22:43
тьфу... точно... не досмотрел...
гляжу на первый пример с положительным счетчиком
C++
1
p = new char[614400000U];
автоматически думается, что с отрицательным полный аналог ))..
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
08.04.2010, 22:44
fasked, ну вот, скорее всего в это дело и было.
0
Maniac
Эксперт С++
 Аватар для ISergey
1464 / 965 / 160
Регистрация: 02.01.2009
Сообщений: 2,820
Записей в блоге: 1
08.04.2010, 22:54
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Genius Ignat Посмотреть сообщение
Если соблюдать правила хорошего тона можно обойтись и без исключений пример:
C++
1
2
3
4
5
6
7
int main(){
int *p = NULL;
p = new int(0);
if(p==NULL)return -1;
else delete p;
return 0;
}
И к чему это?..
оператор new генерирует исключение std::bad_alloc, тоесть

C++
1
2
Emploee *ptr = new Emploee; // генерирует исключение при нехватки памяти..
if(ptr == 0) ... // Мало вероятно что условие сработает когда либо...
Если охото чтобы new возвращал 0, делайте так..
C++
1
2
   char *ptr = new (nothrow) char; // Вернет 0 при нехватке памяти...
   if(ptr == 0){/*....*/}
0
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
08.04.2010, 23:10
ISergey:
То что вы процитировали не я придумал а более опытные программисты...

Работа с динамической памятью и указателями это работа сапера
нужно быть предельно аккуратным: соблюдать правила придуманные умными людьми,
а так же использовать опыт этих людей: изложенный в умных книгах.
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
08.04.2010, 23:26
Genius Ignat, ISergey прав, согласно стандарту в случае ошибки оператор new возбуждает исключение std::bad_alloc. В связи с эти проверка на NULL не уместна.
1
0 / 0 / 0
Регистрация: 08.04.2010
Сообщений: 10
09.04.2010, 00:20  [ТС]
Цитата Сообщение от CyBOSSeR Посмотреть сообщение
Может быть от того что оператор new принимает аргумент типа size_t, он же unsigned int?
Почему же тогда во втором случае исключение bad_alloc обработать не удается?
0
Эксперт С++
 Аватар для CyBOSSeR
2348 / 1721 / 149
Регистрация: 06.03.2009
Сообщений: 3,675
09.04.2010, 00:31
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
1261 / 799 / 108
Регистрация: 16.09.2009
Сообщений: 2,010
09.04.2010, 11:54
Не большой итог, который я подвел для себя.

По мне так лучше не исключение а 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.04.2010, 11:54
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение/ Перевод https:/ / **********/ gallery/ thinkpad-x220-tablet-porn-gzoEAjs . . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru