Исключительная ситуация, генерируемая оператором new

Следует отметить, что некоторые компиляторы поддерживают генерацию исключений в случае ошибки выделения памяти посредством оператора new, в частности исключения типа bad_alloc. Оно может быть перехвачено и необходимым образом обработано. Ниже в программе рассмотрен пример генерации и обработки исключительной ситуаций bad_alloc. Искусственно вызывается ошибка выделения памяти и перехватывается исключительная ситуация.

#include <new>

#include <iostream>

using namespace std;

int main()

{ double *p;

try{

while(1) p=new double[100]; // генерация ошибки выделения памяти

}

catch(bad_alloc exept) { // обработчик xalloc

cout<<"Возникло исключение"<<exept.what()<<endl;

}

return 0;

}

В случае если компилятором не генерируется исключение bad_alloc, то можно это исключение создать искусственно:

#include <new>

#include <iostream>

using namespace std;

int main()

{ double *p;

try{

if(!(p=new double[100000000])) // память не выделена p==NULL

throw bad_alloc; // генерация ошибки выделения памяти

}

catch(bad_alloc exept) { // обработчик bad_alloc

cout<<"Возникло исключение "<<exept.what()<<endl;

}

return 0;

}

Результатом работы программы будет сообщение:

Возникло исключение bad allocation

Оператор new появился в языке C++ еще до того, как был введен механизм обработки исключительных ситуаций, поэтому первоначально в случае ошибки выделения памяти этот оператор просто возвращал NULL. Если требуется, чтобы new работал именно так, надо вызвать функцию set_new_handler() с параметром 0. Кроме того, с помощью set_new_handler() можно задать функцию, которая будет вызываться в случае ошибки выделения памяти. Функция set_new_handler (в заголовочном файле new) принимает в качестве аргумента указатель на функцию, которая не принимает никаких аргументов и возвращает void.

#include<new>

#include<iostream>

using namespace std;

void newhandler( )

{ cout << "The new_handler is called: ";

throw bad_alloc( );

return;

}

int main( )

{ char* ptr;

set_new_handler (newhandler);

 

try {

ptr = new char[~size_t(0)/2];

delete[ ] ptr;

}

catch( bad_alloc &ba) {

cout << ba.what( ) << endl;

}

return 0;

}

Результатом работы программы является

The new_handler is called: bad allocation

В слассе new также определена функция _set_new_handler, аргументом которой является указатель на функцию, возвращающую значение типа int и получающую аргумент типа size_t, указывающий размер требуемой памяти:

#include <new>

#include <iostream>

using namespace std;

int error_alloc( size_t ) // size_t unsigned integer результат sizeof operator.

{ cout << "ошибка выделения памяти" <<endl;

return 0;

}

int main( )

{

_set_new_handler( error_alloc );

int *p = new int[10000000000];

return 0;

}

Результатом работы функции является:

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

В случае, если память не выделяется и не задается никакой функции-аргумента для set_new_handler, оператор new генерирует исключение bad_alloc.