c++ - 返回空指针的用户定义的 operator new

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

我知道那里有相当多的 C++ 常见问题解答(以及关于 SO 的答案)说没有必要检查普通 new 表达式的返回值是否为 null,因为普通 new 表达式通过抛出异常来指示失败。他们基本上声明普通的 new 表达式永远不会返回 null。 (“普通新表达式”是指不是 nothrow 的新表达式)。

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

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

根据语言规范,如果我的 ::operator new 被声明为非抛出,那么我可能/应该通过返回一个空指针来指示内存分配失败。所以,让我们这样做吧

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

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

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

如果上面的代码没问题,那么我假设当有人说一个普通的新“从不返回空指针”时,他们是在假设标准库提供的 ::operator new 没有被替换。这个假设是否正确?

最佳答案

可以替换的运算符如下

[替换.函数]

(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 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else throw a bad_alloc exception. This requirement is binding on a replacement version of this function.

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

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

7 Required behavior: Return a non-null pointer to suitably aligned storage (3.7.4), or else return a null pointer. This nothrow version of operator new returns a pointer obtained as if acquired from the (possibly replaced) ordinary version. This requirement is binding on a replacement version of this function.

关于c++ - 返回空指针的用户定义的 operator new,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26621607/

相关文章:

c++ - map/unordered_map 插入期间内存分配失败

android - 使用新 API 添加联系人时出现问题

c++ - 为什么我的函数是 "missing argument lists"?

c++ - 如何使用C++标准库网络TS在服务器和客户端之间发送消息

java - 我从 : Object selectedValue = jPane. getValue(); 只得到 null (jPane = 新 JOptionPane(...)

android - 带有 parcelable 的 EXTRA 结果为 NULL 但没有罚款

c++ - 动态声明数组背后的静态声明

c++ - C 的数据结构/抽象数据类型,其作用类似于 C++ 中的 vector

c++ - 部分破坏的物体?

sql - 为什么 PostgreSQL COPY 命令不允许数组中存在 NULL 值?