C++ 运算符new,带有空异常规范,在分配返回0时调用构造函数

C++ 运算符new,带有空异常规范,在分配返回0时调用构造函数,c++,g++,standards,new-operator,C++,G++,Standards,New Operator,我有以下声明: void * operator new (size_t s, PersistentMemory * m) throw() {return m->allocatePersistentMemory(s);} 我在启动时测试内存耗尽,结果是m->allocatePersistentMemory(s)返回0。New然后使用this的空指针调用构造函数 但是,基于C++ 7.3标准第3.7.3.1段3: 未能分配存储的分配函数可以调用 当前安装的新_处理器(18.4.2.2)

我有以下声明:

void * operator new (size_t s, PersistentMemory * m) throw()
   {return m->allocatePersistentMemory(s);}
我在启动时测试内存耗尽,结果是
m->allocatePersistentMemory(s)返回0。New然后使用
this
的空指针调用构造函数

但是,基于C++ 7.3标准第3.7.3.1段3:

未能分配存储的分配函数可以调用 当前安装的新_处理器(18.4.2.2)(如有)。[注:A] 程序提供的分配函数可以获取 当前使用set_new_handler函数安装的新_handler (18.4.2.3)。]如果分配函数声明为空 异常规范(15.4)throw()未能分配存储,因此 应返回空指针。任何其他失败的分配功能 分配存储只能通过抛出 std::bad_alloc(18.4.2.1)类或从 标准::坏的

我的理解是,使用
m->allocatePersistentMemory
returnnull应该会导致整个
操作符new()throw()
在不调用构造函数的情况下返回null。我是否在其他地方遗漏了一些可以覆盖这个的条件

谢谢

C++03标准第5.3.4(13)节规定:

[注意:除非分配函数声明为空 异常规范(15.4),
throw()
通过抛出bad_alloc异常来分配存储(第15条,
18.4.2.1);否则返回非空指针。如果使用空异常规范声明分配函数,
throw()
, 它返回null以指示分配存储失败,并返回非null 否则为指针。]如果分配函数返回null, 不应进行初始化,不应执行释放功能 则新表达式的值应为null

短语“不应进行初始化”意味着不会调用构造函数


有趣的是——除非我读错了规范——当分配函数指定
throw()
并返回null时,“new”调用本身的值为null。我一直认为这是不可能的(例如,请参阅上的几乎所有答案)。

我怀疑您不是在调用您认为正在调用的

void*myalloc(size_t){return 0;}
void*运算符new(size_t s)throw(){return myalloc(s);}
结构Foo{
std::字符串s;

Foo(){std::cout感谢您的额外参考。我工作的环境是异常和标准库恐惧症,而不是使用跳转缓冲区(setjmp)目前还没有,所以我有很大的动力去寻找一种解决方法,它不会用单独的分配、测试和布局新闻来代替一切。这是宏的一部分,它将运算符new的专门定义合并到每个类定义中,所以在这种情况下没有全局
ooperator new(size_t s,PersistentMemory*m)throw();
。尽管如此谢谢:)@ScriptedNight:仍然可能是另一个
新的
操作符被调用。Placement
新的
,或
新的[]
也应该被选中。多亏了这个额外的推送,你是对的。我希望为这个类定义的宏没有被使用,而是有自己的自定义版本。@user315052:为什么两者都在VS2010上运行良好?
void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}
void *myalloc (size_t) { return 0; }
void * operator new (size_t s) throw() { return myalloc(s); }
struct Foo {
    std::string s;
    Foo () { std::cout << this << std::endl; }
    void * operator new (size_t s) { return myalloc(s); }
};
int main () {
    Foo *f = new Foo;
    if (f == 0) std::cout << "f is NULL" << std::endl;
}