如何调用删除的nothrow版本?

bjs*_*123 12 c++ memory-management

我有以下代码,不编译:

int *p = new(nothrow) int;
delete (nothrow) p; //Error
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

错误C2440:'删除':无法从'const std :: nothrow_t'转换为'void*'

nothrow版本delete存在吗?如果是这样,我该如何调用它?


在C++:The Complete Reference中,它给出了它存在,但我在网上看到了不同的意见,因此产生了混乱.

MSDN也谈到它的存在,但我找不到如何在代码中使用它.

在这里,有些人说没有这样的事情.

GMa*_*ckG 17

一个std::nothrow_t释放函数存在,但你不能用一个调用它delete的表达.

解除分配功能是为了完整性.如果一个new表达式失败,因为异常的,编译器需要释放它通过分配的内存operator new匹配调用operator delete.所以需要有一个operator delete接受a std::nothrow_t,允许这个.

(也就是说,一般来说,new带有表单的表达式new (args...) T将通过调用来分配内存operator new(sizeof(T), args...)."匹配"意味着operator delete使用相同的参数调用,除了第一个.)

请注意,您可以直接致电运营商:operator delete(memory, std::nothrow);.但是,delete表达式永远不会使用其他参数调用全局释放函数.


所以你可以用"召唤"它:

struct always_throw
{
    always_throw() { throw std::exception(); }
};

new (std::nothrow) always_throw;
Run Code Online (Sandbox Code Playgroud)

在某些时候,这将通过调用来分配内存:

void* __memory = operator new(sizeof(always_throw), std::nothrow);
Run Code Online (Sandbox Code Playgroud)

由于对象的初始化抛出,编译器需要使用匹配的释放函数释放已分配的内存,因此它会:

operator delete(__memory, std::nothrow);
Run Code Online (Sandbox Code Playgroud)

调用std::nothrow_t版本.


Mic*_*eyn 5

没有这样的形式delete,因为delete没有抛出,因为:

  1. 它不执行任何分配.
  2. 它经常用在不应该抛出的析构函数中!

使用nothrownew版本创建的项目将返回NULL而不是抛出bad_alloc异常.delete在NULL上使用是完全有效的,所以没有它应该抛出的情况.

  • 这个答案仍然是错误的,或者至少是模棱两可的.没有`delete`表达式可以调用`operator delete(...,std :: nothrow)`,但该运算符仍然存在. (3认同)