Обработка отказов new с использованием функции set_new_handler

Существует дополнительное средство, которое можно применить для

реализации обработки отказов new. Функция set_new_handler (с прототипом в

заголовочном файле <new>) принимает в качестве аргумента указатель на

функцию, которая не принимает аргументов и возвращает void. Этот указатель

регистрируется как функция, которая должна вызываться при отказах new. Тем

самым программисту предоставляется стандартный метод обработки всех

отказов new вне зависимости от того, в каком месте программы возникла

ошибка. После того как обработчик new зарегистрирован в программе вызовом

set_new_handler, операция new при отказах не будет выбрасывать

исключений bad_alloc; вместо этого она будет пересылать ошибку

зарегистрированному обработчику.

Если new удалось выделить память, она возвращает указатель на нее. Если

память выделить не удается и никакой функции обработчика new с помощью

set__new_handler зарегистрировано не было, операция new выбрасывает

исключение bad_alloc. Если память выделить не удается и была

зарегистрирована функция обработчика new, то вызывается эта функция. Стандарт C++

определяет, что функция обработчика new должна выполнить одно из следующих

действий:

1. Увеличить объем доступной памяти путем освобождения других областей

динамической памяти (либо попросить пользователя закрыть другие

приложения) и возвратиться к операции new, чтобы возобновить

попытки выделения памяти.

2. Выбросить исключение типа bad_alloc.

3. Вызвать функцию abort или exit (обе из заголовочного файла <cstdlib>)

для завершения программы.

Программа на рис. 16.7 демонстрирует set_new_handler. Функция

customNewHandler (строки 14-18) печатает сообщение об ошибке (строка 16),

а затем завершает программу вызовом abort (строка 17). Вывод показывает,

что программа выполнила всего две итерации цикла, после чего new потерпела

неудачу и активировала функцию customNewHandler. У вас вывод

программы может отличаться от нашего в зависимости от объема физической памяти,

дискового пространства, доступного для виртуальной памяти на вашей

системе, и используемого компилятора.

// Рис. 16.7: test7.cpp

// Демонстрация set_new__handler.

#include <iostream>

using std::cerr;

using std::cout;

#include <new> // стандартная операция new и set__new_handler

using std::set_new_handler;

#include <cstdlib> // прототип функции abort

using std::abort;

using std::endl;

// обработать неудачу выделения памяти

void customNewHandler()

{

cerr << "customNewHandler was called" << endl;

std::abort();

} // конец функции customNewHandler

// применение set_new__handler для обработки исключения new

int main()

{

double *ptr[ 50 ];

// указать, что при неудачном выделении памяти

// должна вызываться функция customNewHandler

set_new_handler (customNewHandler);

// выделить память для ptr[ i ]; при неудаче выделения памяти

// будет вызвана функция customNewHandler

for (int i = 0; i < 50; i++)

{

ptr[ i ] = new double[ 50000000 ]; // возможно исключение

cout << "Allocated 50000000 doubles in ptr[ " << i << " ]\n";

} // конец for

return 0;

} // конец main

/*

Allocated 50000000 doubles in ptr[ 0 ]

Allocated 50000000 doubles in ptr[ 1 ]

customNewHandler was called

Abnormal program termination

*/


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: