Estoy seguro de que este código debería ser ilegal, ya que claramente no funcionará, pero parece estar permitido por el C++ 0x FCD.Legalidad de usar el operador delete en un puntero obtenido de la colocación new
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
Tal vez uno de sus abogados de idiomas puede explicar cómo lo prohíbe la norma.
Hay también una forma de matriz:
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
This is the closest question pude encontrar.
EDIT: yo no voy a comprar el argumento de que los argumentos de la lengua Restricción de la norma para funcionar void ::operator delete(void*)
se aplican de una manera significativa al operando de delete
en un eliminar la expresión. En el mejor de los casos, la conexión entre los dos es extremadamente tenue, y varias expresiones son permitidas como operandos a delete
que no son válidas para pasar a void ::operator delete(void*)
. Por ejemplo:
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;
}
espero que esto muestra que si un puntero puede ser pasado a void operator delete(void*)
no influye en si mismo puntero puede ser utilizado como el operando de delete
.
FYI: El FCD (N3092) ya no es el último borrador. El último borrador es N3225. He mantenido actualizada la [página wiki de la etiqueta C++ - 0x] (http://stackoverflow.com/tags/c%2b%2b0x/info) con un enlace al último borrador del PDF. –
Tenga en cuenta que 5.3.5/2, que cubre esto, se ha modificado en el último borrador. Ahora dice que el puntero puede ser "un puntero a un objeto no array creado por una _new-expression_ previa", y una _new-expression_ incluye incluir nuevas expresiones. No creo que sea así. –
@James: Muchas gracias por el nuevo borrador. Y 5.3.5 es exactamente la sección que creo que debería prohibir esto, pero no es así. ¿Podría mirar mi respuesta (me estoy preparando para seleccionar cualquier cambio de idioma del nuevo borrador) y dejarme saber si cree que tiene alguna relación con esta pregunta? –