Intereting Posts
Пространственная и временная локальность Как я могу объявить переменную по абсолютному адресу с GCC? Вызов функции DDOT в библиотеке BLAS Как защитить динамический символ от перезаписывания вторым динамическим символом? Спящий за миллисекунды в Windows, Linux, Solaris, HP-UX, IBM AIX, Vxworks, Wind River Linux? Почему может glGetString (GL_VERSION) вызвать причину Seg Fault? MPI Spawn: корневой процесс не передает дочерние процессы Как создать DLL Win32 без зависимости от времени выполнения C Прочитайте файл в 2D-массиве в C C – изменить адрес указателя, переданного функции Каковы хорошие тестовые примеры для алгоритмов поиска подстроки и тестирования напряжения? Неверное чтение strdup с размером 4, когда строковый литерал заканчивается символом новой строки \ n Есть ли способ обнаружить, что TCP-сокет был закрыт удаленным одноранговым узлом, не читая его? Импорт списка CSV в структуру массива в C Могу ли я искать каталог и подкаталоги для файлов заголовков?

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

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

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

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

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

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

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

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