c++标准 operator new 自定义错误处理函数
c++中缺省的operator new和operator delete具有非常好的通用性,它的这种灵活性也使得在某些特定
的场合下,可以进一步改善它的性能。尤其在那些需要动态分配大量的但很小的对象的应用程序里,
情况更是如此。
自己重写operator new时很重要的一点是函数提供的行为要和系统缺省的operator new一致。实际做
起来也就是:要有正确的返回值;可用内存不够时要调用出错处理函数;处理好0字节内存请求的情况等。
c++标准operator new 的伪代码如下:
void * operator new(size_t size) // operator new还可能有其它参数 if (size == 0) { // 处理0字节请求时, } while (1) { if (分配成功) // 分配不成功,找出当前出错处理函数 if (globalhandler) (*globalhandler)(); }
|
上面的代码清楚地说明了这一点——while (1)将导致无限循环。
要跳出循环的办法是错误处理函数即new_handler必须满足下列条件之一:
1.产生更多的可用内存。这将使operator new下一次分配内存的尝试有可能获得成功。
实施这一策略的一个方法是:在程序启动时分配一个大的内存块,然后在第一次调用new-handler时释放。
2. 安装另一个不同的new-handler函数。如果当前的new-handler函数不能产生更多的可用内存,
可能它会知道另一个new-handler函数可以提供更多的资源。这样的话,当前的new-handler可以安装另一个
new-handler来取代它
(通过调用set_new_handler)。下一次operator new调用new-handler时,会使用最近安装的那个。
3. 卸除new-handler。也就是传递空指针给set_new_handler。
没有安装new-handler,operator new分配内存不成功时就会抛出一个标准的std::bad_alloc类型的异常。
4.抛出std::bad_alloc或从std::bad_alloc继承的其他类型的异常。这样的异常不会被operator new捕捉,
所以它们会被送到最初进行内存请求的地方。(抛出别的不同类型的异常会违反operator new异常规范。
规范中的缺省行为是调用abort,所以new-handler要抛出一个异常时,一定要确信它是从std::bad_alloc继承来的)
5.没有返回。典型做法是调用abort或exit。