with what vallenato usar tag songs questions que preguntas memoria manejo las kpop estatica does disney dinamica dev consultas como canciones array c memory malloc

what - ¿Qué pasa si falla malloc?



tag del vallenato preguntas (7)

En general, una implementación moderna de malloc() devolverá NULL solo como último recurso absoluto, y volver a intentarlo definitivamente no ayudará. Lo único que ayudará será liberar algo de memoria y luego intentarlo de nuevo. Si su aplicación contiene recursos fungibles, este sería el momento de liberarlos y luego darle otra oportunidad.

En algunos entornos, una práctica útil es asignar una pequeña cantidad de memoria como fondo para días de lluvia . Si malloc() alguna vez devuelve NULL , puede liberar ese fondo de días de lluvia y luego asignar los recursos que necesite para poder manejar el error y salir con gracia. Esta era una práctica común cuando se programaba con el viejo Macintosh Toolbox; si malloc() devolvió NULL , podría usar ese espacio para crear un diálogo para informar el problema antes de salir.

Si una asignación de malloc falla, ¿deberíamos intentarlo de nuevo?

En algo como esto:

char* mystrdup(const char *s) { char *ab = NULL; while(ab == NULL) { ab=(char*)malloc(strlen(s)+1); } strcpy(ab, s); return ab; }

¿Es válido el bucle while para verificar la asignación de memoria?


En un programa de un solo hilo, "intentarlo de nuevo" sin liberar memoria entre intentos no tiene ningún sentido práctico. Simplemente se repetirá para siempre.

En un programa de subprocesos múltiples, esto podría "funcionar" si otro subproceso que se ejecuta en paralelo de repente decide liberar algo de su propia memoria. El bucle en tal caso constituiría un bucle clásico de "espera ocupada". Pero incluso en este caso, tal código tiene muy poco valor práctico por más de una razón.


Es increíblemente improbable que esto haga lo que quieres; Si te quedas sin memoria, es probable que te resulten decepcionantes los ciclos de actividad ocupados hasta que obtengas más. Solo debe devolver el NULL al programa de llamada para que pueda lidiar con el agotamiento de los recursos, ya sea liberando la memoria que ya no necesita o devolviendo un error.


Intente aumentar el tamaño del almacenamiento dinámico (memoria reservada para la asignación dinámica).


No nunca. Si malloc devuelve NULL, eso indica un error, y probablemente debería abortar.


Sin argumentar por qué o cuándo sería útil, los intentos de reasignación en un bucle podrían funcionar, al menos en Windows con un código de 64 bits y la configuración predeterminada del archivo de paginación. Además, esto podría comprar sorprendentemente más memoria virtual adicional. Sin embargo, no haga esto en un bucle infinito, sino que utilice un número finito de reintentos. Como prueba, pruebe el siguiente código que simula pérdidas de 1 Mb de memoria. Debe ejecutarlo en la versión de lanzamiento, preferiblemente no en el depurador.

for (int i = 0; i < 10; i++) { size_t allocated = 0; while (1) { void* p = malloc(1024 * 1024); if (!p) break; allocated += 1; } //This prints only after malloc had failed. std::cout << "Allocated: " << allocated << " Mb/n"; //Sleep(1000); }

En mi máquina con 8 Gb de RAM y archivo de páginas administrado por el sistema, obtengo la siguiente salida (creada con VS2013 para x64 target, probada en Windows 7 Pro):

Allocated: 14075 Mb Allocated: 16 Mb Allocated: 2392 Mb Allocated: 3 Mb Allocated: 2791 Mb Allocated: 16 Mb Allocated: 3172 Mb Allocated: 16 Mb Allocated: 3651 Mb Allocated: 15 Mb

No sé la razón exacta de tal comportamiento, pero parece que las asignaciones comienzan a fallar una vez que el cambio de tamaño del archivo de la página no puede mantenerse al día con las solicitudes. En mi máquina, el archivo de paginación creció de 8 gb a 20 Gb después de este bucle (vuelve a caer a 8 Gb después de que el programa se cierra).


malloc () hace todo lo posible para asignar memoria. Si falla, en lugar de volver a intentar asignar memoria en un bucle de tiempo (el programa podría quedarse atascado allí para siempre), intente liberar algo de memoria contenida en algún otro proceso o hilo, si puede y luego vuelva a intentarlo.

Otra alternativa sería aumentar la memoria, al aumentar el archivo de intercambio o la memoria de paginación, sobre la marcha, desde el propio código (pero es peligroso y no preferible) o hacerlo manualmente.

La mejor manera de evitar tales problemas es calcular o estimar el requisito de memoria, mientras se escribe el código.