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

时间:2014-10-29 01:56:28

标签: c++ null new-operator standards-compliance

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

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

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

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

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

int main() {
  int *i = new int;
}

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

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

1 个答案:

答案 0 :(得分:1)

您可以替换的运算符如下

[replacement.functions]

(2.1) — operator new(std::size_t)
(2.2) — operator new(std::size_t, const std::nothrow_t&)
(2.3) — operator new[](std::size_t)
(2.4) — operator new[](std::size_t, const std::nothrow_t&)
(2.5) — operator delete(void*)
(2.6) — operator delete(void*, const std::nothrow_t&)

void *operator new(size_t s) throw()无效, 要在出现错误时抛出

[new.delete.single]

void* operator new(std::size_t size);
  

3必需行为:返回非null 指针以适当对齐   存储(3.7.4),否则抛出bad_alloc异常。 此要求   绑定在此功能的替换版本

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

void* operator new(std::size_t size, const std::nothrow_t&) noexcept;
  

7必需行为:返回非空指针以进行适当对齐   存储(3.7.4),否则返回空指针。这个没有版本   operator new返回一个获得的指针,好像从中获取的一样   (可能被替换)普通版。这个要求对a有约束力   这个功能的替代版本。