void a(){}
set_new_handler(a);
int *p=new int[100000000000];
既然set_new_handler只是设置函数 它返回上次先前那new-handler
自然operator new不是调用它来调用new-handler
如果内存不足时 我想知道在C++内部 在的那里 以何种方式调用我设置这个new-handler
再有就是 在重载的operator new操作中又是如何 调用new-handler的
1。global operator new( ::operator new )一般是被这样实现的:
void *operator new(size_t size)
{
if (size == 0)
size = 1;
void *last_alloc;
while (!(last_alloc = malloc(size)))
{
if (_new_handler)
(*_new_handler)();
else
throw std::bad_alloc(); // Or return 0;
}
return last_alloc;
}
2。global set_new_handler()( ::set_new_handler() )应该是这样实现的:
new_handler set_new_handler(new_handler p)
{
old_handler = _new_handler;
_new_handler = p;
return old_handler;
}
具体的实现在c runtime library里可以找到。
这样利用_new_handler完成了他们之间的沟通。
2。在你说的这种情况中:
class x {
public:
static new_handler set_new_handler(new_handler p);
static void * operator new(size_t size);
private:
static new_handler currenthandler;
};
x::set_new_handler()和x::operator new()都会模仿global的版本行为,
并把实际操作转发给global版本:
new_handler x::set_new_handler(new_handler p)
{
new_handler oldhandler = currenthandler;
currenthandler = p;
return oldhandler;
}
void * x::operator new(size_t size)
{
new_handler globalhandler = // 安装x的new_handler
std::set_new_handler(currenthandler);
void *memory;
try { // 尝试分配内存
memory = ::operator new(size); // !!这个地方有可能调用你的new_handler(currenthandler);请参考上面::operator new()的实现。
}
catch (std::bad_alloc&) { // 恢复旧的new_handler
std::set_new_handler(globalhandler);
throw; // 抛出异常
}
std::set_new_handler(globalhandler); // 恢复旧的new_handler
return memory;
}
仔细研究一下,当你写下下面这些代码时将发生什么事情:
void nomorememory();
// x的对象分配内存失败时调用的new_handler函数的声明
x::set_new_handler(nomorememory);
// 把nomorememory设置为x的new-handling函数
// 此时x::currenthandler为nomorememory
x *px1 = new x;
// new x;这句将有两个动作:
// 1。调用x::operator new分配内存,这是因为x中的operator new定义屏蔽了
// ::opertor new的定义(注意:operator new只分配内存,并不构造实例)
// 2。调用x::x()构造实例,这部分工作由编译器完成。
// 对1。参考上面x::operator new的工作过程,可以知道,它是如何利用::set_new_handler
// 把x::currenthandler设置成全局的_new_handler,并在完成工作后恢复它的。
// 而在设置之后,x::operator new会调用::operator new,在::operator new的
// 工作过程中,如果分配失败,会调用全局的_new_handler(参考::operator new的实
// 现),而此时它正是x::currenthandler。
综上,我前帖中说:
“在重载的operator new操作中又是如何 调用new-handler的”
operator new不会调用new-handler
---------------
个人以为是没有错的。它只是简单的把它移交给::operator new。
3。关于“任何版本的operator new都只分配内存,不构造实例。”
这就是说写 x *p = new x; 并不是只调用x::operator new。
看看这个例子:
struct test
{
test(int i = 1) : i_(i) {}
int i_;
static void *operator new(size_t size)
{
cout < < "test::operator new called " < < endl;
return ::operator new(sizeof(test));
}
};
void main()
{
test *p = new test;
cout < < p-> i_ < < endl;
p = (test*)test::operator new(sizeof(test));
cout < < p-> i_ < < endl;
}
运行结果:
test::operator new called
1
test::operator new called
-842150451