这是运营商new的伪代码:
while (true)
{
Attempt to allocate size bytes
if (the allocation was successful)
return (a pointer to the memory);
// The allocation was unsuccessful; find out what the
// current new-handling function is
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
if (globalHandler)
(*globalHandler)();
else
throw std::bad_alloc();
}
问题:
1)为什么第一次将0作为参数传递给set_new_handler函数?
2)它表示当分配失败时,调用new_handler函数,尝试分配momory,当且仅当cant不能产生更多内存时,它返回指向已分配内存开始的指针,或者如果它不能,它会抛出bad_alloc exeption或返回null指针和其他正文工作,它会抛出bad_alloc exeption。 我的问题是为什么new_handler函数有时会抛出异常,如果它可以返回空指针,否则body会这样做?
答案 0 :(得分:5)
1)为什么第一次将0作为参数传递给set_new_handler函数?
根据docs此代码:
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
将
(1)将处理程序设置为空指针(作为参数传递)
(2)将当前处理程序的函数指针检索到globalHandler
变量
(3)将处理程序设置回原来的状态(无论globalHandler现在指向什么)
执行此操作以检索指向当前处理程序的函数指针。
分配失败时,调用new_handler函数, 尝试分配momory
未知。我不知道它在哪里分配任何内存,因为它没有代码。用户可以在新处理程序内自由执行任何操作,但分配内存是我要做的最后一件事。事实上,适当的行为是释放一些记忆。
当且仅当不能产生更多内存时,它 返回指向已分配内存开始的指针,如果它不能,则抛出bad_alloc exeption或返回空指针
错误。 new_handler
不返回任何内容,它是typedef
到函数指针,不接受任何参数并返回void
:
typedef void (*new_handler)();
和body工作,它会抛出bad_alloc exeption
else
块仅在没有安装处理程序时使用(它是空指针),而不是在new_handler
"失败时#34;或抛出异常或其他
这样读:
void* operator new (std::size_t size, optional blah blah here) blah blah here
{
while(true) // until universe exists (or a nearest power station)
{
// Try to allocate somehow
// Allocation failed
// Retrieved `global_handler` - a pointer to `void (*new_handler)` somehow
if (globalHandler) // global_handler is not null pointer?
{
(*globalHandler)(); // no, invoke it and loop again
}
else
{
throw std::bad_alloc(); // it's null, nothing to do, exception, sorry
}
}
}
另见: How should I write ISO C++ Standard conformant custom new and delete operators?
答案 1 :(得分:3)
这是前C ++ 11代码,其中获取当前新处理程序的唯一方法是通过稍微hackish方法调用set_new_handler
来设置一个新处理程序,这也恰好返回以前的处理程序。现在我们有get_new_handler
,这样我们就可以避免set-the-handler-to-null-pointer-to-original-the-then-then-restore-the-value-circumlocution。
换句话说,
new_handler globalHandler = set_new_handler(0);
set_new_handler(globalHandler);
是一种更复杂(也更危险)的写作方式
new_handler globalHandler = get_new_handler();
在C ++ 11中。
新处理程序的返回类型为void
- 它不返回指针。实际上从新的处理程序返回(而不是抛出异常或只是终止程序)本质上意味着“再试一次”。