Прежде чем прочитать этот вопрос, я никогда серьезно не относился к обработке исключений. . Теперь я вижу необходимость, но все еще чувствую: «Написание кода, безопасного для исключений, очень сложно».
См. Этот пример в принятом ответе на этот вопрос:
void doSomething(T & t)
{
if(std::numeric_limits<int>::max() > t.integer) // 1. nothrow/nofail
t.integer += 1 ; // 1'. nothrow/nofail
X * x = new X() ; // 2. basic : can throw with new and X constructor
t.list.push_back(x) ; // 3. strong : can throw
x->doSomethingThatCanThrow() ; // 4. basic : can throw
}
Как говорится в ответе, я могу легко предложить базовую гарантию, используя std::unique_ptr
. Однако, когда я ловлю std::bad_alloc
, я не знаю, происходит ли это в push_back
или x->doSomethingThatCanThrow()
, поэтому я не могу знать, является ли t.list по-прежнему «хорошим» или его последний элемент не полностью подготовлен. Тогда единственный выбор - отбросить t, показать пугающее сообщение и прервать выполнение, если t имеет важное значение для всей программы.
В коде с надежной гарантией проблем нет, но «он может стать дорогостоящим» (в этом примере используется копия большого списка) и не очень удобочитаем.
Возможным решением может быть new
ожидание освобождения памяти, удаление наиболее раздражающего исключения std::bad_alloc
. Тогда 2. и 3. не будут выбрасываться (при условии, что конструкция и копирование X
всегда успешны). Я могу просто заключить 4. в блок попытки и обработать исключения здесь (и pop_back список). Тогда функция обеспечит гарантию отсутствия перетаскивания, и в списке всегда будут хорошие вещи.
Пользователям будет наплевать на разницу между 100% ЦП и 100% ОЗУ. Когда они видят, что программа зависает, они закрывают другие программы, поэтому new
находит достаточно памяти и продолжает работу.
Мой вопрос: можно ли это реализовать? Есть ли что-нибудь новенькое, ожидающее, пока освободится память? Могу ли я применить его глобально (например, #define new ...
), чтобы библиотеки до стандартизации C ++ могли выжить во временном 100% ОЗУ?
new
100 ТБ памяти, когда у вас всего 4 ГБ? Вы ждете вечно? - person Mysticial   schedule 03.12.2013std::bad_alloc
и100% RAM usage
абсолютно не связаны. - person Joker_vD   schedule 03.12.2013std::bad_alloc
вызвано исчерпанием адресного пространства вашей программы, а не ограничениями физической памяти. Вы можете выделитьnew std::vector<char>(1024 * 1024 * 1024, 'x')
на машине с 256 МБ ОЗУ, и она не будет сброшена и будет работать нормально (если будет медленно). - person Joker_vD   schedule 03.12.2013auto* p = new std::vector<char>((std::vector<char>::size_type)(10.0 * 1024 * 1024 * 1024), 'x');
выдаетstd::bad_alloc
, когда я выключаю виртуальную память в Windows 8.1 с физической памятью 4 ГБ. Если я установил для виртуальной памяти значение auto, вы правы, она работает, но работает медленно (100% дискового ввода-вывода). x64 сборка. - person jingyu9575   schedule 03.12.2013