Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
32 / 30 / 4
Регистрация: 01.02.2014
Сообщений: 878

Как отлавливать exceptions от stl?

09.08.2015, 23:35. Показов 2047. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Использую вектор,
в описнии написано

Return value
C++ (Qt)
1
f a reallocation happens, the storage is allocated using the container's allocator, which may throw exceptions on failure (for the default allocator, bad_alloc is thrown if the allocation request does not succeed).
что такое bad_alloc? строка? число? как его отлавливать?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
09.08.2015, 23:35
Ответы с готовыми решениями:

Как правильно сделать рефакторинг Exceptions
Подскажите, как правильно сделать рефакторинг Exceptions. Например вынести в отдельный метод и тп. На разных сайтах все пишут по-разному....

Как отлавливать исключения?
Вы пишете код для простой арифметического библиотеки. Вы решили создать метод с именем Devide, который принимает два аргумента (х и у), и...

Как отлавливать p2p трафик
Добрый день! Подскажите, как возможно вычленить p2p трафик? Запретить торренты?

15
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.08.2015, 23:42
Лучший ответ Сообщение было отмечено mh-coder как решение

Решение

C++
1
2
3
4
5
6
7
8
try
{
    // Write your code here.
}
catch (std::bad_alloc const & Exc)
{
    // Process the exception.
}
P.S.
Есть мнение, что отлавливать bad_alloc - пустая затея, потому что вряд ли вы в
такой ситуации сможете сделать что-то адекватное из-за нехватки памяти.
Разумеется, если только это не результат попытки выделить несколько гигов за
один new...
1
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,028
Записей в блоге: 1
10.08.2015, 00:11
Цитата Сообщение от Убежденный Посмотреть сообщение
потому что вряд ли вы в
такой ситуации сможете сделать что-то адекватное из-за нехватки памяти.
хотя бы корректно завершить программу и отписаться об ошибке, а то так и из main'а вылетит
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
10.08.2015, 09:22
Цитата Сообщение от Убежденный Посмотреть сообщение
вряд ли вы в
такой ситуации сможете сделать что-то адекватное из-за нехватки памяти
Так вот буквально намедни как раз в теме Croessmah и обсуждали такое. пришли к выводу, что можно зарезервировать кусок памяти при старте программы как раз на такой случай, для корректного завершения хоть.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.08.2015, 10:01
А в этом есть какой-то смысл ? Ну упало приложение - и пусть, разве не так ?
Система покажет стандартное окошко, что, де, приложение было неожиданно
завершено и будет закрыто, отчет находится там-то и там-то и включает
такие-то данные. Все. В чем смысл еще делать "что-то" ?

Ну может быть, такое можно сделать для того, чтобы успеть сохранить
открытый документ. Но я сильно сомневаюсь, что получится это
сделать в условиях нехватки памяти (если только речь не идет о
банальном FlushFileBuffers/CloseHandle).
1
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
10.08.2015, 10:33
Цитата Сообщение от Убежденный Посмотреть сообщение
А в этом есть какой-то смысл ? Ну упало приложение - и пусть, разве не так ?
Почему сразу упало? Скажем, попытались мы открыть файл. Открывашка вылетела с исключением bad_alloc. Мы это исключение поймали, выдали сообщение "невозможно открыть файл - памяти маловато" и работаем дальше.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
10.08.2015, 11:11
Убежденный, соединения мож какие успеть закрыть, установить перезапуск программы. Придумать можно что-нибудь.
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.08.2015, 11:34
Видимо, здесь следует разделять два случая:

1) Когда bad_alloc является ожидаемым, как в примере, который привел Renji.
Тут да, я согласен, наверное можно и нужно навесить try/catch и обработать
исключение соответствующим образом, после чего продолжить работу.

2) Когда bad_alloc возникает как следствие исчерпания свободной памяти.
И вот в данном случае мы вряд ли уже можем что-то сделать.
Если памяти нет, то вызов любой функции, которая пытается хоть чуть-чуть еще
захапать для своей работы, будет завершаться неудачей. Простое присваивание
или копирование std::string уже вызовет проблемы. Короче, поведение catch-
хэндлера станет непредсказуемым. И в итоге оригинальное исключение
будет замаскировано, а вместо него мы получим неизвестно что.
0
Почетный модератор
Эксперт С++
 Аватар для SatanaXIII
5851 / 2862 / 392
Регистрация: 01.11.2011
Сообщений: 6,906
10.08.2015, 11:39
Цитата Сообщение от Убежденный Посмотреть сообщение
Если памяти нет, то вызов любой функции, которая пытается хоть чуть-чуть еще
захапать для своей работы, будет завершаться неудачей.
Вот именно для этого и нужно было выделить просто кусок мертвой памяти в начале работы программы. Резерв типа
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.08.2015, 11:44
SatanaXIII, тогда пойдем дальше: как вы гарантируете, что
все функции, вызываемые внутри catch-хэндлера, будут использовать
именно эту, заранее зарезервированную, память ?
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
10.08.2015, 11:50
Цитата Сообщение от Убежденный Посмотреть сообщение
SatanaXIII, тогда пойдем дальше: как вы гарантируете, что
все функции, вызываемые внутри catch-хэндлера, будут использовать
именно эту, заранее зарезервированную, память ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
char*Ballast=new char[1000000];//резерв
int main()
{
    try
    {
        char*test=new char[1000000000];//выделяем много памяти
    }
    catch(const bad_alloc&)
    {
        //сбрасываем балласт. Теперь свободной памяти прибавилось
        delete[]Ballast;
        Ballast=0;
        //делаем что-то аварийное
        ...
        //по завершении возвращаем балласт на место
        Ballast=new char[1000000];
    }
}
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,028
Записей в блоге: 1
10.08.2015, 12:40
Цитата Сообщение от Убежденный Посмотреть сообщение
тогда пойдем дальше: как вы гарантируете, что
все функции, вызываемые внутри catch-хэндлера, будут использовать
именно эту, заранее зарезервированную, память ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <cstdlib>
 
 
int main()
{
 
    std::vector<int> vec(10) ;
    try
    {
        while ( malloc(1000000) ) ;
        while ( malloc(10000) ) ;
        while ( malloc(100) ) ;
        while ( malloc(1) ) ;
        vec.at(11) ;
    }
    catch ( const std::exception & e )
    {
        std::cout << "result exception: " << e.what() << std::endl ;
    }
}
http://rextester.com/CNCLH28446

А если соорудить к этому коду такое
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector>
#include <cstdlib>
 
 
 
void destroy_reserve () noexcept ;
void * buffer_setup ( std::size_t size ) ;
void my_new_handler () ;
 
void * buffer = nullptr ;
static void * ptr_once = ( std::set_new_handler( my_new_handler ) , (void)ptr_once , buffer_setup ( 10240 ) ) ;
 
void destroy_reserve () noexcept
{
    printf ( "%s: %p\n" , "destroy_reserve: " , buffer ) ;
    free ( buffer ) ;
    buffer = nullptr ;
}
 
 
 
void * buffer_setup ( std::size_t size )
{
    static void * ptr_once = ( atexit ( destroy_reserve ) , (void)ptr_once ,  buffer = malloc ( size ) ) ;
    return buffer ;
}
 
 
void my_new_handler ()
{
    if ( buffer == nullptr )
        throw std::bad_alloc() ;
    destroy_reserve () ;
 
}
 
 
 
 
 
int main()
{
 
    std::vector<int> vec(10) ;
    try
    {
        while ( malloc(1000000) ) ;
        while ( malloc(10000) ) ;
        while ( malloc(100) ) ;
        while ( malloc(1) ) ;
        vec.at(11) ;
    }
    catch ( const std::exception & e )
    {
        std::cout << "result exception: " << e.what() << std::endl ;
    }
}
http://rextester.com/TVQMQ97476
???
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
10.08.2015, 13:56
Цитата Сообщение от Renji
C++
1
2
3
4
//сбрасываем балласт. Теперь свободной памяти прибавилось
delete[]Ballast;
Ballast=0;
//делаем что-то аварийное
А где гарантия, что другой поток не захапает свободную память
между вызовом delete и "делаем что-то аварийное" ?

Croessmah, по Вашему примеру: у std::cout есть гарантия, что он не трогает new/delete ?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,028
Записей в блоге: 1
10.08.2015, 14:16
Цитата Сообщение от Убежденный Посмотреть сообщение
Croessmah, по Вашему примеру: у std::cout есть гарантия, что он не трогает new/delete ?
Я не встречал (или успешно пропустил мимо) такого. Дело не в этих гарантиях, а в том, что мы всё-таки можем задать хоть какую-то политику в new_handler при bad_alloc.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
10.08.2015, 14:42
Цитата Сообщение от Убежденный Посмотреть сообщение
А где гарантия, что другой поток не захапает свободную память
между вызовом delete и "делаем что-то аварийное" ?
Если у нас многопоточность тогда да, сложнее. Простейшее решение - заморозить все остальные потоки через SuspendThread и его аналоги. Но будет платформозависимо (как я понимаю, STL аналогов не имеет).
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
11.08.2015, 13:18
Цитата Сообщение от Renji Посмотреть сообщение
Если у нас многопоточность тогда да, сложнее. Простейшее решение - заморозить все остальные потоки через SuspendThread и его аналоги. Но будет платформозависимо (как я понимаю, STL аналогов не имеет).
А можно просто забить и пусть падаете себе.
И либо переписываем прогу, либо пусть пользователь разгружает/покупает память.

Хотя конечно такие отловы вероятно имеют смысл в специфического рода программах, которые просто монопольно отжирают память.
Но в большинстве случаев вероятно нехватка памяти - кривая логика программ или несоответствие сис.требованиям.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.08.2015, 13:18
Помогаю со студенческими работами здесь

Как отлавливать события wx.CheckListBox
Добрый вечер. self.spis_log = wx.CheckListBox(frame.panel_msg, 318, choices = self.login_uch, size = (430, 140), pos = (5, 55)) ...

[Exceptions] Как правильно внедрить новое исключение в существующее API?
Есть API, которое я не могу менять. Там есть код, в котором в catch блоке возвращают null. Я прочитал что это плохой дизайн т.к форсит...

Как отлавливать события мыши в Excel?
privet vsem, ya tolko tolko isuchaju vba v excel, xotel pojmat sobitija mishi, to isk kogha shelknjot na kakom to sheet naprimer A:1 to...

Как отлавливать ввод каждого символа
Всем привет. Ловлю ивенты TextView определим TextView.OnEditorActionListener интерфейс, в методе onEditorAction. Но событие ввода...

Как отлавливать нажатие клавиш глобально
Всем здрасте. Прошу Вашей помощи в развязании следующей проблемы. Пишу инструмент для программы ArcGis, инструмент написал все отлично...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru