分段错误而不是构造函数调用

8 c++ constructor

我正在尝试对内置分配函数进行一些修改:

#include <iostream>
#include <cstdlib>
#include <new>

struct A
{
    int a;
    A(){ std::cout << "Constructor\n"; a = 3; }
    void* operator new(std::size_t t) noexcept
    {
        ::operator new(t);
        return NULL;
    }
};

int main()
{
    new A();
}
Run Code Online (Sandbox Code Playgroud)

演示

而不是构造函数调用我得到了segmentation fault.你能解释一下这种行为吗?

Ben*_*igt 5

你有一个错误,因为调用::operator new()可能会抛出std::bad_alloc,违反了特定于类的分配器的异常规范(zybox的答案显示了如何解决这个问题).但是,这种小程序不太可能发生.尽管我找不到必须在同一范围内找到两者的明确要求,但在operator new()不提供的情况下覆盖也是一个坏主意operator delete().

从分配器返回空指针既合法又是指示分配失败的正确方法.在3.7.4.1中,标准说:

无法分配存储的分配函数可以调用当前安装的新处理函数(18.6.2.3)(如果有).[注意:程序提供的分配功能可以new_handler使用std::get_new_handler函数(18.6.2.4)获取当前安装的地址.- 结束注释]如果使用非抛出异常规范(15.4)声明的分配函数无法分配存储,则它应返回空指针.任何其他无法分配存储的分配函数都应仅通过抛出与std :: bad_alloc(18.6.2.1)类型的处理程序(15.3)匹配的类型的异常(15.1)来指示失败.

然后在5.3.4中:

如果分配函数返回null,则不进行初始化,不应调用释放函数,并且new-expression的值应为null.

该代码是合法的路径上::operator new()没有抛出-表达式new A()main()的计算结果为空指针,因为它永远不会被解除引用这是确定.

你也不应该得到构造函数调用.你应该得到的是内存泄漏,因为没有::operator delete()::operator new(t)你的分配器内部相对应的调用.

  • 我希望有一条评论可以解释这个问题.如果某人有一个标准引文制作成员`operator new`而没有`operator delete`未定义的行为,我很感兴趣. (3认同)