Prueba de fuga de memoria para cada programa C
Una publicación de blog claramente humorística propone “arreglar” las fugas de memoria en C interceptando `malloc` y guardando cada asignación en una lista global, de modo que los detectores de fugas vean todo como todavía alcanzable, a costa de provocar fugas reales y corromper la memoria. Los comentaristas desmenuzan por qué esto es inseguro y engañoso, lo contrastan con herramientas reales como Valgrind y LeakSanitizer, y lo usan para hablar de cuándo está bien no liberar memoria (procesos de corta vida, arenas, FaaS) frente a cuándo son esenciales una gestión de memoria robusta, RAII o la recolección de basura.
Gravedad de la propuesta
- Muchos comentaristas ven la publicación claramente como una broma, pensada para demostrar lo trivial que es engañar a los detectores de fugas, no como una técnica de producción.
- Otros señalan que el código parece lo bastante plausible como para que programadores de C con menos experiencia puedan confundirlo con una solución real, lo que les preocupa.
Crítica técnica del wrapper malloc “bigbucket”
- El wrapper solo lleva un registro de las asignaciones en una lista global; nunca elimina entradas, incluso cuando el código del usuario llama a
free. - Esto produce fugas reales: la memoria del heap usada por la lista de seguimiento crece sin límite, y los punteros almacenados quedan colgando después de los
free. - Puede agotar la memoria incluso en programas que liberan todo correctamente dentro de un bucle.
- No es seguro para hilos y paga un coste alto al llamar a
dlsymen cada asignación. - Algunos señalan que podrías “completar” la broma redefiniendo
freecomo una operación vacía para evitar por completo los punteros colgantes.
Definición de fugas frente a crecimiento de memoria sin límite
- Varios apuntan que la memoria “alcanzable” puede seguir siendo una fuga en la práctica; los lenguajes con GC pueden filtrar memoria mediante referencias olvidadas.
- Otros enfatizan que lo que realmente importa es el consumo de memoria sin límite, no si la memoria es técnicamente alcanzable.
No liberar a propósito en sistemas reales
- Se dan muchos ejemplos en los que no liberar es intencional y aceptable: programas de corta duración, procesos por solicitud al estilo CGI/PHP, asignadores por arena/por solicitud, sistemas HFT, algunos motores de juegos/audio, misiles o sistemas embebidos especializados, y servidores que se reinician periódicamente.
- Algunos sostienen que liberar al salir del programa a menudo no sirve de nada e incluso puede perjudicar el rendimiento (por ejemplo, fallos de página al desmantelar heaps grandes).
Herramientas de detección de fugas y estrategias prácticas
- Los comentaristas recomiendan herramientas reales como Valgrind y LeakSanitizer, y patrones como arenas, diseño sin fugas por módulo y liberación selectiva de los “caminos calientes” que dominan las asignaciones.
- Un truco mencionado: ejecutar la limpieza completa solo cuando se está bajo un detector de fugas (por ejemplo, detectando Valgrind en tiempo de ejecución).
Metadatos y problemas de medición
- El hilo invoca repetidamente la idea de que si solo optimizas para “no tener fugas bajo la herramienta X”, la gente manipulará esa métrica (ley de Goodhart).
- Varios señalan que, en bases de código grandes, las fugas reales son menos comunes que el hinchamiento de memoria por datos retenidos pero no usados, que es más difícil de encontrar y afecta a todos los lenguajes.