用户定义的operator new,返回空指针

AnT*_*AnT 5 c++ null standards-compliance new-operator

我知道很少有C++常见问题解答(以及SO上的答案)说没有必要检查普通new-expression的返回值为null,因为普通的new-expression通过抛出异常来表示失败.他们基本上声明普通的new-expression永远不会返回null.(通过"普通新表达式"我的意思是一个不是一个新表达式nothrow).

然而,尽管这看起来像一个非常基本的问题,我突然意识到,当他们给出答案时,我不明白他们做出的具体假设(如果有的话).

特别是,我想知道我是否允许重载基本的普通形式::operator new以始终返回空指针,因此期望所有使用该运算符的普通新表达式现在也将返回空指针.

根据语言规范,如果我::operator new被声明为非投掷,那么我可能/将通过返回空指针来指示内存分配失败.所以,让我们这样做

void *operator new(size_t s) throw() {
  return 0;
}

int main() {
  int *i = new int;
}
Run Code Online (Sandbox Code Playgroud)

在我的实验中,上面的new-expression确实成功返回一个空指针.那么,我是否违反了上述代码中的任何规则?宣布平原::operator new为非投掷是否合法?

如果上面的代码没问题,那么我认为当有人声明一个普通的新"永不返回空指针"时,他们会假设标准库提供的版本::operator new没有被替换.这个推定是否正确?

use*_*267 2

可以替换的运算符如下

\n\n

[替换功能]

\n\n
(2.1) \xe2\x80\x94 operator new(std::size_t)\n(2.2) \xe2\x80\x94 operator new(std::size_t, const std::nothrow_t&)\n(2.3) \xe2\x80\x94 operator new[](std::size_t)\n(2.4) \xe2\x80\x94 operator new[](std::size_t, const std::nothrow_t&)\n(2.5) \xe2\x80\x94 operator delete(void*)\n(2.6) \xe2\x80\x94 operator delete(void*, const std::nothrow_t&)\n
Run Code Online (Sandbox Code Playgroud)\n\n

void *operator new(size_t s) throw()无效,如果出错则必须抛出

\n\n

[新.删除.单]

\n\n
void* operator new(std::size_t size);\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

3 必需的行为:返回一个非空指针到适当对齐的存储(3.7.4),否则抛出异常bad_alloc此要求\n 对此函数的替换版本具有约束力

\n
\n\n

但是,您可以安全地将非抛出noexcept重载替换为始终返回 null 的函数,因为调用这些重载的人必须了解此行为并相应地检查返回值。显然,除非传递 nothrow 标签,否则它们不会被调用,即int* i = new (std::nothrow) int;

\n\n
void* operator new(std::size_t size, const std::nothrow_t&) noexcept;\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

7 所需行为:返回一个非空指针到适当对齐的存储(3.7.4),否则返回一个空指针。此无抛出版本operator new返回一个指针,就像从(可能被替换的)普通版本获取的一样。此要求对此函数的替换版本具有约束力。

\n
\n