Законность использования оператора delete для указателя, полученного в результате размещения new

Я чертовски уверен, что этот код должен быть незаконным, так как он явно не будет работать, но, похоже, он разрешен 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 в выражении удаления . В лучшем случае связь между ними крайне непостоянна, и ряд выражений разрешены в качестве операндов для удаления , которые нельзя передать на ] void :: оператор 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 .

12
задан Community 23 May 2017 в 11:51
поделиться