我知道很少有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
版本。没有被取代。这个推定是否正确?
答案 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有约束力 这个功能的替代版本。