函数
<new>

operator delete

普通 (1)
void operator delete (void* ptr) throw();
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw();
placement (3)
void operator delete (void* ptr, void* voidptr2) throw();
普通 (1)
void operator delete (void* ptr) noexcept;
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
placement (3)
void operator delete (void* ptr, void* voidptr2) noexcept;
普通 (1)
void operator delete (void* ptr) noexcept;
nothrow (2)
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) noexcept;
placement (3)
void operator delete (void* ptr, void* voidptr2) noexcept;
带大小 (4)
void operator delete (void* ptr, std::size_t size) noexcept;
nothrow 带大小 (5)
void operator delete (void* ptr, std::size_t size,                      const std::nothrow_t& nothrow_constant) noexcept;
释放存储空间
默认的*析构函数*(单对象形式)。

(1) 普通 delete
释放 ptr 指向的内存块(如果非空),释放之前通过调用 operator new 分配给它的存储空间,并使该指针位置失效。
(2) nothrow delete
同上(1)
(3) placement delete
什么都不做。
(1) 普通 delete
释放 ptr 指向的内存块(如果非空),释放之前通过调用 operator new 分配给它的存储空间,并使该指针位置失效。
(2) nothrow delete
同上(1)
默认定义调用第一个版本(1): ::operator delete(ptr)
(3) placement delete
什么都不做。
(1) 普通 delete
释放 ptr 指向的内存块(如果非空),释放之前通过调用 operator new 分配给它的存储空间,并使该指针位置失效。
(2) nothrow delete
同上(1)
默认定义调用第一个版本(1): ::operator delete(ptr)
(3) placement delete
什么都不做。
(4) (5) 带大小
分别同(1)(2)
默认定义简单地调用相应版本:(1)(2)
它们为自定义实现提供了优化点:它们被调用时会传入与相应*分配函数*调用时相同的*大小*参数。

请注意,如果其中一个带*size*的签名被替换,那么它对应的无*size*的版本也应该被替换(反之亦然)。即:如果(1)(4)被替换,两者都应该被替换。同样,如果(2)(5)被替换,两者都应该被替换。

默认的*分配和析构函数*是标准库的特殊组件;它们具有以下独特属性
  • 全局: 所有 operator delete 的重载都在全局命名空间中声明,而不是在 std 命名空间内。
  • 隐式: 析构版本(即除(3)外的所有版本)在 C++ 程序的每个翻译单元中*隐式声明*,无论是否包含头文件<new>
  • 可替换:析构版本(即除(3)外的所有版本)也*可替换*:程序可以提供自己的定义来替换默认提供的定义,或者可以为特定类型重载它。自定义定义应释放 ptr 引用的存储。

operator delete 是一个常规函数,可以像任何其他函数一样显式调用。但在 C++ 中,delete 是一个具有非常特定行为的运算符:带有 delete 运算符的表达式首先调用适当的析构函数(对于类类型),然后调用*析构函数*。

类对象的*析构函数*是名为 operator delete 的成员函数(如果存在)。在所有其他情况下,它是全局函数 operator delete(即此函数——或更具体的重载)。如果 delete 表达式前面带有*作用域运算符*(即 ::operator delete),则只考虑全局*析构函数*。

使用全局*析构函数*的 delete 表达式始终调用单参数签名(例如(1))。
使用全局*析构函数*的 delete 表达式始终使用接受指针(例如(1))或指针和大小(例如(4))的签名。总是优先使用带*size*的版本(4),除非重载提供了与指针类型更匹配的匹配。

其他签名((2)(3))*从不*被*delete表达式*调用(delete 运算符始终调用此函数的普通版本,并且每个参数只调用一次)。这些其他签名仅在对象构造失败时由*new表达式*自动调用(例如,如果对象的构造函数在由带 nothrow 的*new表达式*构造时抛出异常,则会调用接受 nothrow 参数的匹配 operator delete 函数)。

非成员*析构函数*不得在全局命名空间以外的命名空间作用域中声明。

参数

ptr
指向要释放的内存块的指针,类型转换为 void*
如果这是一个*空指针*,则函数不执行任何操作。
如果非空,此指针值应由先前调用 operator new 返回,并且尚未通过先前调用此函数被释放。
如果非空,此指针值应由先前调用 operator new 返回,并且尚未通过先前调用此函数被释放。
如果实现具有*严格指针安全性*,则此指针还应为*安全派生指针*。
nothrow_constant
常量 nothrow。此参数在默认定义中被忽略。
nothrow_t 是常量 nothrow 的类型。
voidptr2
void指针。该值在默认定义中被忽略。
size
在分配内存块时传递给*分配函数*的第一个参数。
std::size_t 是无符号整数类型。

返回值



示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// operator delete example
#include <iostream>     // std::cout

struct MyClass {
  MyClass() {std::cout <<"MyClass constructed\n";}
  ~MyClass() {std::cout <<"MyClass destroyed\n";}
};

int main () {
  MyClass * pt = new (std::nothrow) MyClass;
  delete pt;    // implicitly calls ::operator delete(pt)

  return 0;
}

输出

MyClass constructed
MyClass destroyed


数据竞争

修改 ptr 引用的存储。
调用*分配和析构函数*会重用相同的存储单元,并按照一个总顺序进行,其中每次析构都发生在下一次分配之前。
这同样适用于此函数的自定义替换的可观察行为。

异常安全

无异常保证:此函数从不抛出异常。

请注意,无效的 ptr 值会导致未定义行为。
请注意,无效的 ptr 值或与*分配函数*传递的*size*值不匹配的值会导致未定义行为。

另见