pointer - malloc sizeof
¿Fprintf usa malloc() debajo del capó? (3)
Quiero un controlador mínimo o-damn-malloc-just-failed, que escribe algo de información en un archivo (probablemente solo un error estándar). Preferiría usar fprintf () en lugar de write (), pero esto fallará si fprintf () trata de malloc ().
¿Existe alguna garantía, ya sea en el estándar C, o incluso en glibc de que fprintf no hará esto?
El estándar C no garantiza que fprintf
no llame a malloc
debajo del capó. De hecho, no garantiza nada sobre lo que sucede cuando anulas malloc
. Debe consultar la documentación de su biblioteca de C específica, o simplemente escribir su propia función similar a fprintf
que hace llamadas directas, evitando cualquier posibilidad de asignación de pila.
Las únicas funciones en las que puede estar razonablemente seguro de que no llamará a malloc
son aquellas marcadas como POSIX como async-signal-safe . Ya que no se requiere que malloc
sea seguro para señales asíncronas (y dado que es esencialmente imposible hacer que sea seguro para señales asíncronas sin que sea ineficiente), las funciones seguras para señales asíncronas normalmente no pueden llamarlo.
Dicho esto, estoy casi seguro de que las funciones printf
de glibc (incluidas fprintf
e incluso snprintf
) pueden usar malloc
para algunas cadenas de formato (¿todas?).
No, no hay garantía de que no lo haga. Sin embargo, la mayoría de las implementaciones que he visto tienden a usar un búfer de tamaño fijo para crear la cadena de salida con formato (a) .
En términos de glibc ( fuente aquí ), hay llamadas a malloc
dentro de stdio-common/vfprintf.c
, que gran parte de la familia de printf
utiliza en el extremo inferior, por lo que no confiaría en eso si fuera usted. Incluso las llamadas de salida de cadena-búfer como sprintf
, que puede pensar que no lo necesitarían, parecen resolverse hasta esa llamada, después de configurar algunos manejadores de cadena similares a FILE
- vea libio/iovsprintf.c
.
Mi consejo es que luego escriba su propio código para hacer la salida a fin de garantizar que no se realicen asignaciones de memoria bajo el capó (y espero, por supuesto, que la write
sí misma no lo haga (a diferencia de *printf
que lo haga)). De todas formas, como es probable que no vayas a generar muchas cosas convertidas (probablemente solo "Dang, I done run outta memory!"
), La necesidad de una salida con formato debería ser cuestionable.
(a) Las consideraciones ambientales de C99 dan una indicación de que (al menos) algunas implementaciones tempranas tenían un límite de amortiguamiento. De mi memoria de las cosas del Turbo C, pensé que 4K era sobre el límite y, de hecho, C99 afirma (en 7.19.6.1 fprintf
):
El número de caracteres que puede producir cualquier conversión individual será de al menos 4095.
(El mandato para el C89 era codificar la práctica existente, no crear un nuevo lenguaje, y esa es una de las razones por las cuales algunos de estos máximos mínimos se incluyeron en la norma, se llevaron a iteraciones posteriores de la norma).