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版本.
没有这样的形式delete,因为delete没有抛出,因为:
使用nothrownew版本创建的项目将返回NULL而不是抛出bad_alloc异常.delete在NULL上使用是完全有效的,所以没有它应该抛出的情况.