new失败了会发生什么
当用new来申请一块内存的时候,如果申请失败了,编译器会抛出一个异常(新式)或者返回一个null(旧式)。
在抛出异常或者返回null之前,编译器会先调用一个new_handler的方法,可以理解为错误处理函数。
namespace std {
typedef void (*new_handler) ();
new_handler set_new_handler(new_handler p) throw();
}
new_handler是一个函数指针,指向void()函数。在调用new_handler指向的方法前,需要先设置一下,也就是set_new_handler方法。
这个方法参数是个new_handler,返回也是个new_handler。参数指定new失败后调用的那个函数的指针,返回的是原先指定的那个函数的指针。当调用的函数指针是null时,新式new将抛出bad_alloc异常。
自己写一个new_handler
class专属new_handler。一个类想自己写一个new_handler需要干两件事
- 写set_new_handler:让用户指定类专属new_handler
- 写operator new:让编译器用类专属new_handler替换global_new_handler(默认的)
举个例子,加我们有Widget类,我们想给这个类设计一个new_handler。
class Widget {
public:
static std::new_handler set_new_handler(std::new_handler p) throw();
static void* operator new(std::size_t size) noexcept(false);
private:
static std::new_handler currentHandler;
};
std::new_handler Widget::currentHandler = nullptr;
set_new_handler要干的事。
std::new_handler Widget::set_new_handler(std::new_handler p) throw() {
std::new_handler oldHandler = currentHandler; // 保存旧的new_handler
currentHandler = p; // 用新的替换旧的
return oldHandler; // 返回旧的
}
这里文字叙述一下operator new要干的事
- 调用标准的set_new_handler:将new_hander设置为global_new_handler(默认的)
- 调用标准的global operator new:实际分配内存
- 如果分配内存出错了,就调用自己的new_handler。如果还是不行抛出bad_alloc异常。
- 如果分配内存没错,那就直接返回一个指针。
后面的内容感觉有点跟不上时代了,就不总结了。