Así que quieres soporte para asignadores personalizados en tu biblioteca C
Los asignadores de memoria personalizados para bibliotecas C prometen mejor rendimiento, flexibilidad e integración con herramientas, pero su diseño plantea preguntas difíciles sobre seguridad y practicidad. Los comentaristas debaten APIs que exigen que los llamadores pasen tamaños de objeto, alineación y punteros de contexto: argumentan que esto puede acelerar la asignación y ayudar a depurar, mientras que otros señalan que el código C real a menudo no rastrea estos detalles de forma fiable y podría volverse más frágil. El hilo también contrapone diseños minimalistas de “una sola función de asignación” con interfaces más claras pero más verbosas, y destaca cómo estas decisiones afectan la escalabilidad multihilo, la integración con herramientas como ASAN/valgrind y el soporte de patrones como arenas y asignadores de pila.
Seguridad y corrección de las APIs de asignación
- Varios comentaristas sostienen que exigir el tamaño en free/realloc podría haber evitado muchos errores, pero otros dicen que confiar en tamaños proporcionados por el llamador es peligroso y aun así debe verificarse.
- Algunos señalan que muchos asignadores ya conocen los tamaños mediante metadatos o arenas, así que los argumentos de tamaño extra a menudo solo duplican trabajo, salvo que se traten como sugerencias.
- Hay rechazo a la afirmación del artículo de que los llamadores “siempre” tienen el tamaño original; la gente da contraejemplos realistas en los que no lo tienen.
Paso de información de tamaño y alineación
- Quienes apoyan pasar el tamaño a free dicen que puede evitar búsquedas costosas en arenas/buckets y el acceso a metadatos.
- Otros señalan que los asignadores modernos normalmente pueden recuperar el tamaño de forma barata sin recorridos.
- Varios comentarios sostienen que la alineación extendida debería formar parte de la interfaz; algunos quieren un parámetro de alineación explícito en cada llamada, otros confían en el contexto o en APIs separadas de alloc alineado.
- Hay debate sobre si la alineación es obligatoria (para que free sea correcto) o si puede ser “solo una sugerencia”.
Interfaces de asignador de una sola función frente a múltiples funciones
- Un grupo prefiere una API única del estilo
allocate(ptr, size, ...)que codifica malloc/realloc/free mediante combinaciones de argumentos, citando simplicidad y poco tamaño de implementación (por ejemplo, diseños tipo Lua). - Los críticos dicen que combinar operaciones complica el razonamiento, introduce casos ambiguos (
alloc(NULL, 0)) y dificulta la revisión y las herramientas; prefieren alloc/free/realloc separados.
Asignación gestionada por el llamador frente a asignación gestionada por la biblioteca
- Algunos defienden APIs en las que el llamador asigna, posiblemente mediante patrones de dos pasadas (calcular tamaño y luego escribir), operaciones reanudables o “pasar un callback de asignador”, como en el artículo.
- Otros responden que esto solo funciona para casos simples (por ejemplo, algo tipo
snprintf), mientras que bibliotecas complejas (DOM XML, etc.) inevitablemente asignan internamente y se benefician de asignadores enchufables.
Hilos y rendimiento
- La discusión señala que los asignadores con estado global escalan mal; los cachés locales por hilo más mecanismos para liberaciones desde otros hilos (colas, CAS, bloqueos por clase de tamaño) son mitigaciones comunes.
- Hay interés en cuán simplemente pueden implementarse esos esquemas manteniendo una buena escalabilidad en varios núcleos.
Restricciones reales de C y asignaciones de tamaño cero
- Varios comentarios subrayan que muchas bases de código C existentes no rastrean los tamaños de forma rigurosa, especialmente con cadenas terminadas en null y arrays flexibles.
- Hay debate sobre el significado y la utilidad de
malloc(0)y sobre la señalización en banda con valores numéricos especiales como 0 o -1.
Herramientas e integración
- Algunos enfatizan que las APIs de asignación deberían integrarse con herramientas como ASan y Valgrind; las anotaciones se consideran sencillas pero esenciales.