当 operator new
无法满足某一内存分配需求时,它会抛出异常,在此之前,它会先调用一个客户指定的错误处理函数,即new-handler。为了指定这个函数,客户必须调用 set_new_handler
:
namespace std {
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
}
set_new_handler
的参数是个指针,指向 operator new
无法分配足够内存时该调用的函数,其返回值也是个指针,指向set_new_handler被调用前正在执行的new-handler函数。
你可以这样使用 set_new_handler
:
void outOfMem() {
std::cerr << "Unable to satisfy request for memory\n";
std::abort();
}
int main() {
std::set_new_handler(outOfMem);
int* pBigDataArray = new int[100000]l
...
}
如果new分配内存失败,outOfMem会被调用,程序在输出一个信息后终止。
一个设计良好的new-handler函数必须做以下事情:
- 让更多内存可被使用。 一般做法是使用内存池。
- 安装另一个new-handler。 如果当前的new-handler无法分配更多内存,就可以调用另一个可以分配更多内存的new-handler替换自己。
- 移除new-handler。 将null指针传给set_new_handler,operator new会在内存分配不成功时抛出异常。
- 抛出bad_alloc。 会被传播到申请内存的代码处。
- 不返回。 通常调用abort或exit。
C++并不支持class专属的new-handler,但其实也不需要。你可以令每一个class提供自己的set_new_handler和operator new即可。set_new_handler使客户可以指定class专属的new-handler,operator new确保在分配class对象时用class专属的new-handler替换global new-handler。
请记住
- set_new_handler允许客户指定一个函数,在内存分配无法获得满足时被调用。