2008-10-27 7 views

Respuesta

45

De acuerdo con la norma actual, nueva nunca se regresa NULL , que arroja un std :: bad_alloc lugar. Si no desea que se ejecute nuevo (según el estándar anterior), sino que devuelva NULL, debe llamarlo postfijación con "(std :: nothrow)". decir

Foo* foo = new (std::nothrow) Foo; 

Por supuesto, si usted tiene un conjunto de herramientas muy viejos o rotos posiblemente podría no seguir la norma.

+0

"Nunca se devuelve un valor nulo" ... a continuación, seguir adelante y se contradice :) usando std :: nothrow hace que la primera parte de su declaración falsa :) –

+0

No lo hace falso, solo un poco inconsistente. La versión "normal" de nuevo nunca devuelve NULL. – Gorpik

+1

¡No estaría de más reparar la respuesta! –

0

Por lo general, nadie prueba la devolución de un código nuevo porque Visual Studio ahora arroja el estilo que dice el estándar.

En el código anterior, si se ha realizado un truco para evitar tirar, es mejor que lo pruebe.

+0

¿Qué pasa con la pregunta que implica que el entorno es MS DevStudio? –

+0

Nada. Pero si Visual Studio no hubiera recibido esta solución, entonces sería mucho menos probable que el póster se encuentre en esta situación "Por lo general, nunca veo la prueba de nuevo en C++". Entonces lo expliqué. –

4

Todo depende de qué versión de C++ se dirija al código. La especificación C++ durante mucho tiempo ha establecido que, al menos de forma predeterminada, las fallas en las nuevas provocarán una excepción C++, por lo que cualquier código que realice una prueba sería completamente redundante. La mayoría de la programación hoy en día también apunta a sistemas operativos de memoria virtual donde es casi imposible quedarse sin memoria, Y una condición de memoria insuficiente es tan fatal que dejar que la aplicación falle en el próximo acceso NULO es una buena manera de de terminar.

Está realmente solo en la programación integrada, donde el manejo de excepciones se considera demasiado alto y la memoria es muy limitada, por lo que los programadores se molestan en buscar nuevas fallas.

+0

Capturar la excepción y guardar datos en el disco, podría ser una mejor manera que simplemente dejar que la aplicación se bloquee ... –

+0

¿Pero cómo? El C++ moderno está lleno de creación de objetos por todo el lugar. Cuando falla un "nuevo", es de esperar que los nuevos intentos de nuevos también fallen. Lo que significa que un intento de conservar datos en el disco también fallará. –

+1

"donde es casi imposible quedarse sin memoria" No estoy de acuerdo Es fácil quedarse sin memoria virtual en un proceso de 32 bits - en Windows solo obtiene 2 Gig de espacio de direcciones - cualquier dominio que involucre datos muestreados - video, médicos, etc. .Puede rellenarlo fácilmente o fragmentarlo, lo que lleva a una falla de asignación. – morechilli

3

Como se cita here

"En compiladores cumplen con la norma ISO C++, si no hay suficiente memoria para la asignación, el código se emite una excepción de tipo std :: bad_alloc. Todo el código subsiguiente se interrumpe hasta que el el error se maneja en un bloque try-catch o el programa sale anormalmente. El programa no necesita verificar el valor del puntero, si no se lanzó una excepción, la asignación tuvo éxito ".

7

Todo depende de su compilador VC++ hasta la versión 6 da NULL si el nuevo operador falla, en una aplicación que no es MFC.

Ahora el problema aumenta cuando utiliza, por ejemplo, STL con VC++ 6, porque el STL cumple con los estándares que nunca probará NULL cuando necesita obtener algo de memoria, y adivine qué sucederá en condiciones de poca memoria. ...

Así que para todos los que todavía usan VC++ 6 y STL revisen este artículo para obtener una reparación. Don't Let Memory Allocation Failures Crash Your Legacy STL Application

3
  1. new tiros std::bad_alloc por defecto. Si usa el valor predeterminado, la verificación de null es obsoleta, pero es necesario manejar excepciones.Este comportamiento predeterminado es coherente con el paradigma de seguridad de excepciones de C++: generalmente establece que un objeto está construido o no asignado

  2. si invalida el valor predeterminado utilizando new (std::nothrow), es necesario verificar que no sea válido. "Nuevo" asigna y confirma páginas, por lo que es posible que se quede sin memoria, ya sea porque se agotó los descriptores de página o porque no hay memoria física disponible

  3. investigue la administración de memoria de su sistema operativo. La máquina de referencia C/C++ no sabe cómo administra su sistema operativo su sistema operativo, por lo que confiar en el lenguaje por sí solo no es seguro. Por ejemplo de asignación de memoria que salió mal, leer en C + Linux malloc() overcommit

Cuestiones relacionadas