Исключительная ситуация, генерируемая оператором 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.