关于operator new重载和异常的问题

sun*_*369 3 c++ exception new-operator c++11

为什么这段代码会输出很多“here”?

我认为程序应该在throw std::invalid_argument( "fool" );调用 after 时终止。

#include <memory>
#include <iostream>

void* operator new(std::size_t size)
{
    std::cout << "here" << std::endl;
    throw std::invalid_argument( "fool" );   //commit out this, there would be many many ouputs
    return std::malloc(size);
}

void operator delete(void* ptr)
{
    return free(ptr);
}


int main()
{
    //std::unique_ptr<int> point2int(new int(999));

    int* rawpoint2int = new int(666);
}
Run Code Online (Sandbox Code Playgroud)

pad*_*ddy 8

的文档包含线索std::invalid_argument

由于复制std::invalid_argument不允许引发异常,因此该消息通常在内部存储为单独分配的引用计数字符串。这也是为什么没有构造函数接受的原因std::string&&:无论如何它都必须复制内容。

您可以看到字符串参数是按设计复制的。new这意味着如果您以这种方式抛出此异常,则几乎可以保证重新进入。

您还应该意识到malloccan returnnullptr会违反设计,其中operator new应该返回有效指针或抛出异常。

在这种情况下抛出的正常异常类型是std::bad_alloc。我无法想象你为什么想扔std::invalid_argument。我想您可能在某个构造函数中遇到了这个问题,并决定测试分配本身。

从技术上讲,您可以通过传递默认构造的字符串作为参数来解决该问题:

// ... but, why would you do this?!! :(
throw std::invalid_argument(std::string());  // will not allocate
Run Code Online (Sandbox Code Playgroud)

呃,真恶心。我建议您找到一个更合适的异常来抛出(如果您确实需要一个异常),或者创建您自己的非分配异常。