2010-10-23 5 views
11

tengo el siguiente código, que no se compila:¿Cómo invoco la versión de eliminación de nothrow?

int *p = new(nothrow) int; 
delete (nothrow) p; //Error 

El error que consigo es:

error C2440: 'eliminar': no ​​se puede convertir de 'const std :: nothrow_t' 'nulo *'

¿Existe una versión nothrow de delete? Si es así, ¿cómo puedo invocarlo?


En C++: La referencia completa, se da porque existe pero vi diferentes opiniones en línea, de ahí la confusión.

MSDN también habla de su existencia, pero no pude encontrar cómo se puede usar en el código.

Here, algunas personas dicen que no existe tal cosa.

+0

Su enlace de MSDN habla de la existencia de 'nothrow', pero * que * nunca estuvo en ninguna duda. Es * 'delete' * que todo el mundo te dice que no tiene la versión' nothrow', y tienen razón. –

+3

Si ese libro es el de Schildt, debería (desafortunadamente) tirarlo. Ese tipo es terrible, y no tiene idea de qué está hablando cuando se trata del idioma. – GManNickG

Respuesta

15

A std::nothrow_t existe la función de desasignación, pero no se puede llamar con una expresión delete.

La función de desasignación está ahí para completarla. Si una expresión new falla debido a una excepción, el compilador necesita liberar la memoria que asignó a través de operator new con una llamada correspondiente al operator delete. Entonces debe haber un operator delete que acepte un std::nothrow_t, para permitir esto.

(Es decir, en general, una expresión new con la forma new (args...) T va a asignar memoria con una llamada a operator new(sizeof(T), args...). Para "partido" se refiere a llamar operator delete con los mismos argumentos, excepto la primera.)

Nota puede llamar al operador directamente: operator delete(memory, std::nothrow);. Sin embargo, una expresión delete nunca llama a una función de desasignación global con parámetros adicionales.


Así se puede "llamar" con:

struct always_throw 
{ 
    always_throw() { throw std::exception(); } 
}; 

new (std::nothrow) always_throw; 

En algún momento, esto va a asignar memoria con una llamada a:

void* __memory = operator new(sizeof(always_throw), std::nothrow); 

Desde la inicialización del objeto tiros , el compilador necesita liberar la memoria asignada con una función de desasignación correspondiente, por lo que hace:

operator delete(__memory, std::nothrow); 

Llamando a la versión std::nothrow_t.

5

No existe tal forma de delete, porque delete no tira, ya que:

  1. no realiza ninguna asignación.
  2. ¡Se usa a menudo en destructores que no deberían arrojarse!

Los elementos creados con la versión nothrow de new, devolverán NULL en lugar de arrojar una excepción bad_alloc. Usar delete en NULL es perfectamente válido, por lo que no hay ninguna situación en la que deba arrojarse.

+0

Oh. Pero en referencia completa libro de C++, es dado que existe y vi diferentes opiniones diferentes en internet, de ahí la confusión. – bjskishore123

+1

¿Qué quiere decir con "no fueron asignados desde el montón"? Todavía asigna memoria, simplemente no arrojará si no puede. – GManNickG

+0

Lo sentimos, se actualizó para ser menos confuso y no confundir con nuevo en el lugar ... –

2

Para la mayoría de los propósitos prácticos, solo hay una versión de eliminar. El new(nothrow) está escrito como un nuevo operador de ubicación, pero en su mayor parte, no hay una versión correspondiente para eliminar. La única excepción es una versión de eliminación que se invoca cuando se lanza una ubicación nueva, pero como (en este caso) ha asegurado que el new no puede arrojarse, esa versión de eliminación no es de uso real/ayuda aquí.

Cuestiones relacionadas