Я чертовски уверен, что этот код должен быть незаконным, поскольку он явно не будет работать, но, похоже, он разрешен 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
Может быть, кто-нибудь из вас, языковых юристов, сможет объяснить, почему стандарт запрещает это.
Там также форма массива:
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
Это самый близкий вопрос, который мне удалось найти .
РЕДАКТИРОВАТЬ: я просто не согласен с тем, что аргументы стандартного языка, ограничивающие аргументы функции void ::operator delete(void*)
, каким-либо значимым образом применяются к операнду 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;
}
Надеюсь, это показывает, что возможность передачи указателя в void operator delete(void*)
не имеет никакого отношения к тому, может ли тот же самый указатель использоваться в качестве операнда delete
.