我想要一个最小的o-damn-malloc-just-failed处理程序,它将一些信息写入文件(可能只是标准错误)。我更喜欢使用fprintf()而不是write(),但如果fprintf()本身尝试使用malloc(),这将会失败。
是否有一些保证,无论是在C标准中,还是在glibc中,fprintf都不会这样做?
答案 0 :(得分:21)
不,不能保证它不会赢。但是,我见过的大多数实现都倾向于使用固定大小的缓冲区来创建格式化的输出字符串(a)。
就glibc(source here)而言,是malloc
内stdio-common/vfprintf.c
的调用,很多printf
家庭使用在低端,如果我是你,我不会依赖它。即使像sprintf
这样的字符串缓冲输出调用,您可能认为它不需要它,在设置一些棘手的FILE
之后似乎解决了该调用 - 就像字符串句柄一样 - 请参阅libio/iovsprintf.c
。
我的建议是编写自己的代码来进行输出,以确保没有内存分配(当然,希望write
本身不会这样做(比*printf
做得更un))。由于您可能无论如何都不会输出大量转换的内容(可能只是"Dang, I done run outta memory!"
),因此无论如何都需要格式化输出。
(a) C99环境考虑因素表明(至少)某些早期实施具有缓冲限制。从我对Turbo C的记忆中,我认为4K是关于极限的,事实上,C99状态(在7.19.6.1 fprintf
中):
任何单次转换可以产生的字符数至少应该是 4095。
(C89的任务是编纂现有的做法,而不是创造一种新的语言,这就是为什么这些最小的最大值被置于标准中的一个原因 - 它们被推迟到标准的后续迭代中)。
答案 1 :(得分:8)
C标准并不保证fprintf
不会调用malloc
。实际上,当你覆盖malloc
时,它并不保证会发生什么。您应该参考特定C库的文档,或者只编写自己的fprintf
- 类似函数,它可以直接进行系统调用,避免任何堆分配的可能性。
答案 2 :(得分:4)
您可以合理确定的唯一不会调用malloc
的功能是POSIX标记为 async-signal-safe 的功能。由于malloc
不需要是异步信号安全的(并且因为它基本上不可能使其异步信号安全而不会使它效率低效),异步信号安全功能通常无法调用它。
话虽如此,我几乎可以肯定glibc的printf
函数(包括fprintf
甚至snprintf
)可以并且将malloc
用于某些(全部?)格式字符串。