Ben*_*igt 12 c++ placement-new language-lawyer delete-operator
我确信这段代码应该是非法的,因为它显然不会起作用,但它似乎被C++ 0x FCD所允许.
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X(); // according to the standard, the RHS is a placement-new expression
::operator delete(p); // definitely wrong, per litb's answer
delete p; // legal? I hope not
Run Code Online (Sandbox Code Playgroud)
也许你们中的一位语言律师可以解释标准如何禁止这一点.
还有一个数组形式:
class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X[1]; // according to the standard, the RHS is a placement-new expression
::operator delete[](p); // definitely wrong, per litb's answer
delete [] p; // legal? I hope not
Run Code Online (Sandbox Code Playgroud)
编辑:我只是不买,该标准的语言限制参数函数的参数void ::operator delete(void*)
以任何有意义的方式适用于操作数delete
在delete表达式.在最好的情况,两者之间的连接是极其脆弱的,以及一些表达式是允许作为操作数delete
不属于有效传递给void ::operator delete(void*)
.例如:
struct A
{
virtual ~A() {}
};
struct B1 : virtual A {};
struct B2 : virtual A {};
struct B3 : virtual A {};
struct D : virtual B1, virtual B2, virtual B3 {};
struct E : virtual B3, virtual D {};
int main( void )
{
B3* p = new E();
void* raw = malloc(sizeof (D));
B3* p2 = new (raw) D();
::operator delete(p); // definitely UB
delete p; // definitely legal
::operator delete(p2); // definitely UB
delete p2; // ???
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我希望这表明指针是否可以传递void operator delete(void*)
给与该指针是否可以用作操作数无关delete
.
标准规则在[basic.stc.dynamic.deallocation] p3
否则,
operator delete(void*)
标准库中提供的值应为先前调用operator new(size_t)
或operator new(size_t, const std::nothrow_t&)
在标准库中返回的值之一,并且标准库中提供的值operator delete[](void*)
应为先前调用的值返回的值之一.或者operator new[](size_t)
或operator new[](size_t, const std::nothrow_t&)
在标准库.
除非您覆盖delete
了图书馆operator delete(void*)
,否则您的电话会致电图书馆.既然你没有说过什么,我会假设你没有.
上面的"应该"应该是"行为未定义,如果不是",所以它不会被误认为是可诊断的规则,而不是[lib.res.on.arguments] p1.这已被n3225更正,所以它不能再被误认了.
编译器并不真正关心p
来自放置调用的new
内容,因此它不会阻止您delete
在对象上发出。这样,您的示例就可以被认为是“合法的”。
但这是行不通的,因为delete
无法显式调用“放置”运算符。仅当构造函数抛出异常时才会隐式调用它们,以便析构函数可以运行。