Есть ли что-нибудь новое, что ждет, пока не освободится память?

Перед чтением этот вопрос, Я никогда не относился к обработке исключений серьезно. Теперь я вижу необходимость, но все еще чувствую, что «написание безопасного кода исключений очень сложно».

Посмотрите этот пример в принятом ответе на этот вопрос:

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. в блок try и иметь дело с исключениями здесь (и pop_back список). Тогда функция обеспечит nothrow гарантией, а список всегда будет содержать хорошие вещи.

Пользователи не будут заботиться о разнице между 100% CPU и 100% RAM. Когда они видят зависание программы, они закрывают другие программы так, new находит достаточно памяти и продолжает.

Мой вопрос: это можно реализовать? Есть ли что-нибудь новое, что ждет, пока не освободится память? Могу ли я применить его глобально (например, #define new ...) поэтому библиотеки до стандартизации C ++ могут пережить временную 100% оперативную память?

3

Решение

Это сомнительный дизайн, но вы, безусловно, можете сделать это с помощью «нового обработчика». Новый обработчик по умолчанию просто выбрасывает std::bad_alloc, Если новый обработчик возвращается, new будет цикл, и попытаться выделить снова. Он также используется оператором nothrow new, но std::bad_alloc брошенный новым обработчиком пойман, и NULL вернулся, в таком случае.

Вам просто нужно задавать новый обработчик на ваш заказ void (*)() функция обработчика. По крайней мере, вы можете захотеть уложить процесс на некоторое время — скажем, 1/10 сек. Опять же, в любом случае, программа не сможет продолжить работу — например, в Linux есть «убийца OOM», который может быть настроен администратором.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector