c ++中的operator new,new_handler函数

时间:2015-03-03 04:50:26

标签: c++ memory memory-management new-operator

这是运营商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会这样做?

2 个答案:

答案 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)

  1. 这是前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中。

  2. 新处理程序的返回类型为void - 它不返回指针。实际上从新的处理程序返回(而不是抛出异常或只是终止程序)本质上意味着“再试一次”。