operator new抛出异常的处理

来源:互联网 发布:怎么查看php源代码 编辑:程序博客网 时间:2024/06/06 18:58

operator new在无法完成内存分配请求时会抛出异常(以前的做法一般是返回0,一些旧一点的编译器还这么做,我们也可以恢复到旧的编译器方式

例如:

char * lp = new char[10000000];

如果分配失败,在旧的编译器下会返回0,但是在新的编译器下会抛出异常std::bad_alloc

我们也可以用在新的编译器下不抛出异常而返回0

char * lp = new(nothroe) char[10000000];

 

但是更好的解决方式是使用set_new_handler,它在<new>头文件中的定义大概如下:

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();

可以看到,new_handler是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数。set_new_handler则是一个输入并返回new_handler类型的函数。

set_new_handler的输入参数是operator new分配内存失败时要调用的出错处理函数的指针,返回值是set_new_handler没调用之前就已经在起作用的旧的出错处理函数的指针。

可以象下面这样使用set_new_handler:

// functin to call if operator new can't allocate enough memory
void nomorememory()
{
cerr << "unable to satisfy request for memory/n";
abort();
}
int main()
{
set_new_handler(nomorememory);
int *pbigdataarray = new int[100000000];
...
}

卸除new-handler。也就是传递空指针给set_new_handler。没有安装new-handler,operator new分配内存不成功时就会抛出一个标准的std::bad_alloc类型的异常。

 

 

更一般而好的处理方式是继承模板类

template<class t> // 提供类set_new_handler支持的
class newhandlersupport { // 混合风格”的基类
public:
static new_handler set_new_handler(new_handler p);
static void * operator new(size_t size);

private:
static new_handler currenthandler;
};

template<class t>
new_handler newhandlersupport<t>::set_new_handler(new_handler p)
{
new_handler oldhandler = currenthandler;
currenthandler = p;
return oldhandler;
}

template<class t>
void * newhandlersupport<t>::operator new(size_t size)
{
new_handler globalhandler =
std::set_new_handler(currenthandler);
void *memory;
try {
memory = ::operator new(size);
}
catch (std::bad_alloc&) {
std::set_new_handler(globalhandler);
throw;
}

std::set_new_handler(globalhandler);
return memory;
}
// this sets each currenthandler to 0

template<class t>
new_handler newhandlersupport<t>::currenthandler;

有了这个模板类,对类x加上set_new_handler功能就很简单了:只要让x从newhandlersupport<x>继承:
// note inheritance from mixin base class template. (see
// my article on counting objects for information on why
// private inheritance might be preferable here.)
class x: public newhandlersupport<x> {

... // as before, but no declarations for
}; // set_new_handler or operator new

以上是读 effective C++ 的笔记