Подтвердить что ты не робот

Использует ли fprintf malloc() под капотом?

Мне нужен минимальный обработчик o-damn-malloc-just-failed, который записывает некоторую информацию в файл (возможно, только стандартную ошибку). Я бы предпочел использовать fprintf(), а не write(), но это сильно испортится, если fprintf() сам попытается выполнить malloc().

Есть ли какая-то гарантия, либо в стандарте C, либо даже в glibc, что fprintf не будет делать этого?

4b9b3361

Ответ 1

Нет, нет гарантии, что этого не произойдет. Однако большинство реализаций, которые я видел, обычно используют буфер фиксированного размера для создания форматированной выходной строки (a).

В терминах glibc (источник здесь), есть вызовы malloc внутри stdio-common/vfprintf.c, которые многие из семейства printf используют на нижний конец, поэтому я бы не стал полагаться на него, если бы был вами. Даже вывод строки-буфера вызывает, например, sprintf, который, по вашему мнению, не понадобится, кажется, что он разрешает этот вызов после настройки некоторых сложных FILE -подобных строковых дескрипторов - см. libio/iovsprintf.c.

Мой совет заключается в том, чтобы затем написать свой собственный код для выполнения вывода, чтобы гарантировать, что выделение памяти не выполняется под капотом (и, надеюсь, конечно, что write сам не делает этого (не более чем *printf делать это)). Поскольку вы, вероятно, не собираетесь выводить много преобразованных файлов в любом случае (возможно, просто "Dang, I done run outta memory!"), необходимость форматированного вывода в любом случае должна быть сомнительной.


(a) Экологические соображения C99 указывают на то, что (по крайней мере) некоторые ранние реализации имели предел буферизации. Из моей памяти о вещах Turbo C я думал, что 4K находится на пределе и действительно, C99 состояния (в 7.19.6.1 fprintf):

Количество символов, которые могут быть получены с помощью любого единственного преобразования, должно быть не менее 4095.

(мандат на C89 заключался в кодификации существующей практики, а не в создании нового языка, и одна причина, по которой некоторые из этих минимальных максимумов были помещены в стандарт, - они переносились на последующие итерации стандарта).

Ответ 2

Стандарт C не гарантирует, что fprintf не будет вызывать malloc под капотом. В самом деле, это не гарантирует ничего о том, что происходит, когда вы переопределяете malloc. Вы должны сослаться на документацию для вашей конкретной библиотеки C или просто написать свою собственную функцию fprintf, которая делает прямые системные вызовы, избегая любой возможности выделения кучи.

Ответ 3

Единственные функции, которые вы можете быть разумно уверены, не будут вызывать malloc - это те, которые помечены как безопасные для Async-сигналов POSIX. Поскольку malloc не требуется быть безопасным по отношению к асинхронному сигналу (и поскольку практически невозможно сделать его безопасным для асинхронного сигнала, не делая его непригодным для использования), асинхронные сигнальные функции обычно не могут его вызывать.

Сказав это, я почти уверен, что функции glibc printf (включая fprintf и даже snprintf) могут и будут использовать malloc для некоторых (всех?) строк формата.