Pregunta

Recientemente, trabajo en un programa reproductor de video en Windows para un programa de CCTV. Como el programa tiene que decodificar y reproducir muchas transmisiones de videos al mismo tiempo, creo que podría resolver la situación de que malloc fallará y agrego la comprobación después de cada malloc.

Pero en términos generales, en este código de programas de código abierto que he leído en proyectos de código abierto, rara vez encuentro alguna comprobación del resultado de malloc. Entonces, cuando malloc falla, la mayoría de los programas simplemente se bloquean. ¿No es eso inaceptal?

Mis colegas que escriben programas de servidor en Linux asignarán una memoria suficiente para 100 conexiones de clientes. Entonces, aunque su programa podría rechazar al cliente 101, nunca se encontrará con una falla de malloc. ¿Su enfoque también es adecuado para aplicaciones de escritorio?

¿Fue útil?

Solución

En Linux, malloc () nunca fallará; en cambio, el asesino OOM se activará y comenzará a matar procesos aleatorios hasta que el sistema se caiga. Dado que Linux es el derivado de UNIX más popular en uso hoy en día, muchos desarrolladores han aprendido a nunca verificar el resultado de malloc () . Probablemente sea por eso que sus colegas ignoran las fallas de malloc () .

En los sistemas operativos que admiten fallas, he visto dos patrones generales:

  • Escriba un procedimiento personalizado que verifique el resultado de malloc () y llame a abort () si la asignación falla. Por ejemplo, las bibliotecas GLib y GTK + utilizan este enfoque.

  • Almacene una lista global de " purge-able " asignaciones, como cachés, que se pueden borrar en caso de fallo de asignación. Luego, intente la asignación nuevamente, y si aún falla, repórtelo a través de los mecanismos estándar de informe de errores (que no realizan una asignación dinámica).

Otros consejos

Siga la API estandarizada

Incluso en Linux, ulimit se puede usar para obtener una pronta devolución de error de malloc. Es solo que su valor predeterminado es ilimitado.

Existe una presión definitiva para cumplir con los estándares publicados. En la mayoría de los sistemas, a largo plazo, y eventualmente incluso en Linux, malloc (3) devolverá una indicación correcta de falla. Es cierto que los sistemas de escritorio tienen memoria virtual y paginación de demanda, pero aun así no verifican malloc ( 3) solo funciona en un programa depurado sin pérdidas de memoria. Si algo sale mal, alguien querrá configurar un ulimit y rastrearlo. De repente, la verificación malloc tiene sentido.

Usar el resultado de malloc sin verificar nulo es inaceptable en el código que podría estar abierto para su uso en plataformas donde malloc puede fallar, en aquellos que tenderá a provocar bloqueos y un comportamiento impredecible. No puedo prever el futuro, no sé a dónde irá mi código, así que escribiría código con cheques para que malloc devuelva nulo, ¡mejor morir que comportarse de manera impredecible!

Las estrategias sobre qué hacer si falla Malloc dependen del tipo de aplicación y de la confianza que tenga en las bibliotecas que está utilizando. En algunas situaciones, lo único seguro es detener todo el programa.

La idea de preasignar una cuota conocida de memoria y parcelarla en algunos fragmentos, por lo tanto, evitar el agotamiento de la memoria es buena, si el uso de memoria de su aplicación es predecible. Puede extender esto a escribir sus propias rutinas de administración de memoria para que las use su código.

Depende del tipo de aplicación en la que esté trabajando. Si la aplicación funciona dividida en tareas discretas en las que se puede permitir que una tarea individual falle, entonces se pueden recuperar las asignaciones de memoria de forma correcta.

Pero en muchos casos, la única forma razonable de responder a una falla de malloc es finalizando el programa. Permitir que su código simplemente se bloquee en la inevitable anulación de la referencia logrará eso. Sin duda, siempre sería mejor volcar una entrada de registro o un mensaje de error que explique el error, pero en el mundo real trabajamos en horarios limitados. A veces, el retorno de la inversión del manejo pedante de errores no está allí.

Compruebe siempre y asigne previamente un búfer que se puede liberar en este caso para que pueda advertir al usuario que guarde sus datos y cierre la aplicación.

Depende de la aplicación que escriba. Por supuesto, siempre debe verificar el valor de retorno de malloc (). Sin embargo, manejar OOM con gracia solo tiene sentido en algunos casos, como servicios de sistema cruciales de bajo nivel, o cuando se escribe una biblioteca que podría usarse para ellos. Tener un contenedor de malloc que aborta en OOM es, por lo tanto, muy común en muchas aplicaciones y marcos. A menudo, esos contenedores se denominan xmalloc () o similar.

GLib's g_malloc () también está abortando.

Si va a manejar grandes cantidades de memoria y desea hacer declaraciones a Linux como 'ahora tengo el área de memoria ABC y no necesito la pieza B, haga lo que desee', eche un vistazo a Familia de funciones mmap () / madvise () disponible en la biblioteca GNU C en stock. Dependiendo de sus patrones de uso, el código puede terminar incluso más simple que usar malloc. Esta API también se puede usar para ayudar a Linux a no perder memoria almacenando en caché los archivos que va a leer / escribir solo una vez.

Están bien documentados en la documentación de información de GNU libc.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top