sucede sirve resueltos resuelto que precede para mundo laberinto karel instrucciones ejercicios descargar definidas c++ exception

c++ - resueltos - para que sirve karel



¿Con qué frecuencia verifica una excepción en una nueva instrucción en C++? (10)

Empecé a leer Effective C ++ hoy y llegué al punto en que el autor habla sobre el operador nuevo.

El libro explica muy bien cómo se puede capturar (con varios grados de elegancia) la excepción std :: bad_alloc que el operador nuevo puede generar si se queda sin memoria.

Mi pregunta es: ¿con qué frecuencia verifica el caso cuando no hay suficiente memoria para crear una instancia de un objeto, si es que lo hace? ¿y por qué? ¿Vale la pena la molestia?


Capté excepciones cuando puedo responder esta pregunta:

¿Qué harás con la excepción una vez que la hayas capturado?

La mayoría de las veces, mi respuesta es: "No tengo idea. Quizás mi interlocutor lo sepa". Entonces no entiendo la excepción. Déjalo burbujear a alguien que sabe mejor.

Cuando detecta una excepción y deja que su función continúe ejecutándose, le dice a su programa: "No importa. Aquí todo está bien". Cuando dices eso, por suerte, todo estará mejor. Entonces, si te std::bad_alloc sin memoria, luego de que hayas manejado std::bad_alloc , ya no deberías std::bad_alloc sin memoria. No solo debe devolver un código de error de su función, porque entonces la persona que llama tiene que verificar explícitamente ese código de error, y todavía está sin memoria. Su manejo de esa excepción debería liberar algo de memoria. Vacíe algunos cachés, confíe algunas cosas en el disco, etc. Pero, ¿cuántas de las funciones de su programa realmente desea ser responsable de reducir el uso de memoria de su programa?

Si no puede resolver el problema que provocó la excepción, entonces no maneje la excepción.


Creo que esto depende en gran medida del tipo de aplicaciones que escriba. Si escribiera algo que no afecte la estabilidad global del sistema, digamos un juego o un reproductor de películas, no verificaría esa excepción. Mi aplicación llamaría a std::terminate y podría registrarla en alguna parte, o mi kernel mataría mi programa primero para dar cabida a otros programas.

Si escribo un programa cuya estabilidad se corresponde directamente con la del sistema en el que se ejecuta, digamos un controlador de video o un sistema init, verificaría las excepciones de memoria todo el tiempo (probablemente ajustando las asignaciones en una función) y obtendría algunas memoria de un grupo preasignado en caso de una falla de asignación.

Creo que todo esto depende de la proporcionalidad. ¿Qué ganas de un reproductor de películas increíblemente estable, si comienza a ralentizarse para reproducir películas debido a tu agresiva comprobación?

Por cierto, alguien respondió que malloc no devolverá 0 cuando te quedes sin memoria para algunos sistemas. Así es, pero como señala la página de manual de malloc (específica de Linux)

En caso de que Linux se emplee bajo circunstancias en las que sería menos conveniente perder repentinamente algunos procesos elegidos al azar, y además la versión del kernel es suficientemente reciente, uno puede desactivar este comportamiento excesivo usando un comando como: $ echo 2 > /proc/sys/vm/overcommit_memory

Consulte también el directorio de Documentación del núcleo, archivos vm / overcommit-accounting y sysctl / vm.txt.


Creo que lo más importante es estar siempre consciente de la posibilidad de que se quede sin memoria. Luego decida si le importa o no. Considere probar y atrapar para cada asignación, eso es muy complicado. Elija entre una mayor productividad y un código más simple en comparación con una aplicación que pueda manejar con gracia el caso de falta de memoria. Creo que ambas ganancias son extremadamente valiosas en los contextos correctos, así que elija cuidadosamente.

Sí, puede hacer su vida más fácil al definir una plantilla clase base que proporciona un operador personalizado nuevo y la eliminación del operador y establece un nuevo controlador. Luego puede usar el patrón Curiously Recurring Template para derivar de esta clase base. Sus clases derivadas manejarán con gracia las asignaciones incorrectas, pero aún debe recordar derivar de esa clase base en cada clase nueva que cree. A menudo puede terminar con herencia múltiple, lo que puede traer complejidades propias. No importa lo que hagas para manejar malas asignaciones, tu código no será tan simple como si no te molestaras.

Nunca hay una respuesta a esto. Es una elección que debes hacer, dependiendo del contexto como siempre.


En un sistema que usa memoria virtual, malloc () no devolverá NULL, y new no devolverá std :: bad_alloc; ellos devolverán una dirección virtual. Cuando escribe en la zona de memoria señalada por esta dirección, el sistema intentará asignar la dirección virtual a una dirección física. Si no hay más memoria disponible, obtendrá un error de página.

Así que coges std :: bad_alloc cuando estás en un sistema integrado sin MMU, y espero que puedas hacer algo para liberar algo de memoria.


Nunca. Siempre he considerado que el comportamiento predeterminado (hay una excepción std :: bad_alloc, no se maneja, y por lo tanto el programa termina con un mensaje de error) es bueno para las aplicaciones en las que he trabajado.


Si no se maneja la excepción, su programa se bloqueará y las solicitudes de soporte que reciba se ubicarán entre "no funciona", "se bloquea al azar" y "perdí todo el trabajo de ese día". Si crees que está bien, entonces no vale la pena la molestia.

Lo mínimo que puede hacer es decirle al usuario que se ha quedado sin memoria, al menos dándole una pista de por qué la aplicación se cuelga al azar.

Además, puede intentar conservar los resultados, por ejemplo, guardarlos en un archivo de recuperación. Sin embargo, eso podría ser más fácil de hacer antes de que te topes con el problema.

Sería fabuloso si llegaras a dar un mensaje de error como "No puedes insertar esta imagen porque te quedaste sin memoria". Y continuarías trabajando como si nada hubiera pasado. Sin embargo, esto significa que todo el código detrás de un comando de usuario debe ser transaccional y dar una fuerte garantía de seguridad de excepción .

Por lo tanto, identifique el costo de quedarse sin memoria al azar. En función de eso, evalúe qué "nivel de protección" necesita dar a su usuario.


Si tiene que asignar memoria para, por ejemplo, un búfer de ruta donde sabe que serán solo unos pocos bytes, puede que no valga la pena la molestia.

Pero cuando tiene que asignar memoria para objetos más grandes, como imágenes o archivos, definitivamente debe hacer el control.


Por lo general, no vale la pena a menos que use algo como el patrón RAII (Inicialización de adquisición de recursos es inicialización). En ese caso, es probable que asigne recursos remotos en el constructor, lo que puede incluir el uso de nuevo para crear un búfer grande.

En este caso, es probable que capture la excepción ya que está en un constructor. Además, como está en RAII, es probable que solo el recurso requiera demasiada memoria, lo que le permite proporcionar al usuario mensajes de error más descriptivos.


El problema es que cuando te quedas sin memoria, generalmente no hay mucho que puedas hacer, excepto escribir en un volcado y salir del programa. Por lo tanto, es inútil comprobar cada nuevo en su programa.

Una excepción a esto es cuando asigna memoria para, por ejemplo, cargar un archivo, en cuyo caso solo necesita informar al usuario que no hay suficiente memoria disponible para la operación solicitada.


Solía ​​ser que su programa murió de un modo de muerte swap antes de asignar su último byte posible, con el disco duro accediendo a un archivo de paginación del tamaño de su espacio de direcciones. Pero con los sistemas modernos que tienen 4GB + pero ejecutan procesos de 32 bits, este comportamiento es mucho menos común. Incluso los procesos más grandes pueden obtener toda la RAM física que pueden manejar. En esos casos, pueden quedarse sin memoria antes de que el disco duro muera.

Sin embargo, no hay una estrategia de manejo general. Cualquier proceso que tenga cachés implementados debería eliminarlos, pero una buena memoria caché ya se habría limpiado cuando el sistema operativo indicaba una condición de poca memoria. Un proceso que responde a las solicitudes de los usuarios puede manejar bad_alloc en la granularidad de solicitud del usuario. En general, hay poco beneficio en mantener cualquier memoria asignada, si se queda sin memoria para la acción del usuario. En su lugar, vuelva al estado antes de la acción del usuario. Un proceso no interactivo, por otro lado, podría pasar de un algoritmo O (N) a un O más lento (N log N).