Язык программирования C++ для профессионалов



           

Исчерпание ресурса


Есть одна из вечных проблем программирования: что делать, если не удалось удовлетворить запрос на ресурс? Например, в предыдущем примере мы спокойно открывали с помощью fopen() файлы и запрашивали с помощью операции new блок свободной памяти, не задумываясь при этом, что такого файла может не быть, а свободная память может исчерпаться. Для решения такого рода проблем у программистов есть два способа:

  • Повторный запрос: пользователь должен изменить свой запрос и повторить его.
  • Завершение: запросить дополнительные ресурсы от системы, если их нет, запустить особую ситуацию.

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

В С++ первый способ поддержан механизмом вызова функций, а второй - механизмом особых ситуаций. Оба способа можно продемонстрировать на примере реализации и использования операции new:

#include <stdlib.h>

extern void* _last_allocation;

extern void* operator new(size_t size) { void* p;

while ( (p=malloc(size))==0 ) { if (_new_handler) (*_new_handler)(); // обратимся за помощью else return 0; } return _last_allocation=p; }

Если операция new() не может найти свободной памяти, она обращается к управляющей функции _new_handler(). Если в _new_handler() можно выделить достаточный объем памяти, все нормально. Если нет, из управляющей функции нельзя возвратиться в операцию new, т.к. возникнет бесконечный цикл. Поэтому управляющая функция может запустить особую ситуацию и предоставить исправлять положение программе, обратившейся к new:

void my_new_handler() { try_find_some_memory(); // попытаемся найти // свободную память if (found_some()) return; // если она найдена, все в порядке throw Memory_exhausted(); // иначе запускаем особую // ситуацию "Исчерпание_памяти" }

Где-то в программе должен быть проверяемый блок с соответствующим обработчиком:




Содержание  Назад  Вперед