Un bug en std.Io.Writer.Allocating duplica la memoria reservada al escribir

Fuentes: std.Io.Writer.Allocating ate all my memory

El tipo std.Io.Writer.Allocating de la biblioteca estándar de Zig reserva el doble de memoria de la necesaria al recibir datos a través de su función drain. El problema está en la forma en que el método calcula el espacio extra: tiene en cuenta el parámetro splat (el número de veces que se repite el último fragmento) para cada elemento escrito, incluido el propio fragmento al que splat se aplica. En el caso habitual, con un único dato y splat igual a uno, eso significa reservar dos veces la misma longitud: una por el contenido y otra por la repetición calculada de forma redundante.

El artículo lo ilustra con un ejemplo: al inicializar un Allocating con capacidad 1024 y escribir 1025 bytes de una sola vez, el búfer termina con 3204 bytes en lugar de los aproximadamente 1025 esperados. Si la misma escritura se divide en dos llamadas (1024 bytes más un byte), el resultado es 1668, una cifra mucho más razonable. La diferencia procede de que el cálculo inflado se aplica una sola vez al segundo bloque, no dos veces como ocurre con la llamada única.

El autor reproduce una versión simplificada de drain y señala que el cálculo erróneo reside en la línea que suma bytes.len y splat_len dentro del bucle que recorre los datos. Como ArrayList no implementa splat, no se ve afectado por el mismo fallo. Para casos sencillos de acumulación de bytes, el texto recomienda seguir usando ArrayList. La detección del bug se atribuye a Claude, que identificó la duplicación al revisar el código.