Использует ли fprintf malloc () под капотом? - PullRequest
17 голосов
/ 19 июля 2011

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

Ответы [ 3 ]

21 голосов
/ 19 июля 2011

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

В терминах glibc ( source здесь ), - это звонки на 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 заключался в том, чтобы кодифицировать существующую практику, а не создавать новый язык, и это одна из причин, почему некоторые из этих минимальных максимумов были включены в стандарт - они были перенесеныждем более поздних итераций стандарта).

8 голосов
/ 19 июля 2011

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

4 голосов
/ 19 июля 2011

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

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

...