try sirve qué para libreria excepciones ejemplo definicion catch c++ performance exception-handling readability

c++ - sirve - Nuevo(std:: nothrow) vs. New dentro de un bloque try/catch



try catch definicion (4)

Considera lo que estás haciendo. Estás asignando memoria. Y si por alguna razón la asignación de memoria no puede funcionar, assert . Que es más o menos exactamente lo que sucederá si solo dejas que std::bad_alloc propague nuevamente a main . En una compilación de lanzamiento, donde assert es operativo, su programa se bloqueará cuando intente acceder a la memoria. Por lo tanto, es lo mismo que dejar que surja la excepción: detener la aplicación.

Así que hágase una pregunta: ¿ realmente necesita importar lo que sucede si se queda sin memoria? Si todo lo que hace es afirmar, entonces el método de excepción es mejor, porque no satura su código con afirmaciones aleatorias. Simplemente deja que la excepción vuelva a la main .

Si de hecho tiene una ruta de código especial en el caso de que no pueda asignar memoria (es decir, puede continuar funcionando), las excepciones pueden ser o no un camino a seguir, dependiendo de qué es la ruta de codificación. Si la ruta de código es simplemente un interruptor configurado al tener un puntero nulo, entonces la versión de nothrow será más simple. Si, en cambio, necesita hacer algo bastante diferente (extraer de un búfer estático, o eliminar algunas cosas, o lo que sea), entonces capturar std::bad_alloc es bastante bueno.

Hice algunas investigaciones después de aprender new , a diferencia de malloc() que estoy acostumbrado, no devuelve NULL para las asignaciones fallidas, y encontré que hay dos formas distintas de verificar si las nuevas tuvieron éxito o no. Esas dos maneras son:

try { ptr = new int[1024]; } catch(std::bad_alloc& exc) { assert(); };

y

ptr = new (std::nothrow) int[1024]; if(ptr == NULL) assert();

Creo que las dos formas logran el mismo objetivo (¡corríjanme si me equivoco, por supuesto!), Así que mi pregunta es la siguiente:

que es la mejor opción para comprobar si el new éxito fue, basado enteramente en la legibilidad, la mantenibilidad y el rendimiento, sin tener en cuenta la convención de programación c ++ de facto.


Depende del contexto donde se realiza la asignación. Si su programa puede continuar incluso si la asignación falla (quizás devuelva un código de error a la persona que llama), utilice el método std::nothrow y verifique NULL. De lo contrario, estaría utilizando excepciones para el flujo de control, lo cual no es una buena práctica.

Por otro lado, si su programa necesita tener esa memoria asignada correctamente para poder funcionar, use try-catch para capturar (no necesariamente en las inmediaciones de la new ) una excepción y salir con gracia del programa.


Desde una perspectiva de rendimiento puro, importa poco. Hay una sobrecarga inherente con el manejo de excepciones, aunque esta sobrecarga generalmente vale la pena compensar en la legibilidad y el mantenimiento de la aplicación. Las fallas de asignación de memoria de esta naturaleza no deberían estar en el caso del 99% de su aplicación, por lo que esto debería ocurrir con poca frecuencia.

Desde una perspectiva de rendimiento, generalmente quiere evitar el asignador estándar debido a su rendimiento relativamente bajo de todos modos.

Dicho todo esto, generalmente acepto la versión de lanzamiento de excepción porque generalmente nuestras aplicaciones están en un estado donde si falla la asignación de memoria, hay poco que podamos hacer aparte de salir elegantemente con un mensaje de error apropiado, y ahorramos rendimiento al no requerir la verificación NULL en nuestros recursos recientemente asignados porque, por definición, una falla de asignación moverá el alcance desde donde eso importe.


new se usa para crear objetos, no para asignar memoria, por lo tanto, su ejemplo es algo artificial.

Los constructores de objetos suelen lanzar si fallan. Después de haber recorrido la new implementación en Visual Studio más de unas pocas veces, no creo que el código capte ninguna excepción. Por lo tanto, generalmente tiene sentido buscar excepciones al crear objetos.

Creo que std::bad_alloc se lanza solo si falla la parte de asignación de memoria. No estoy seguro de qué pasará si pasa std::nothrow a new pero el constructor de objetos lanza - hay ambigüedad en los documentos que he leído.

La diferencia de rendimiento entre los 2 enfoques probablemente sea irrelevante, ya que la mayor parte del tiempo del procesador se puede gastar fácilmente en el constructor del objeto o buscando en el montón.

Una regla empírica no siempre es apropiada. Por ejemplo, los sistemas en tiempo real suelen restringir las asignaciones de memoria dinámica, por lo que las new , si las hubiera, probablemente se sobrecarguen. En ese caso, podría hacer uso de un puntero nulo devuelto y manejar el fallo localmente.