Какие функции стандартной библиотеки C используют malloc под капотом - PullRequest
9 голосов
/ 12 декабря 2011

Я хочу знать, какие функции стандартной библиотеки C используют malloc и free под капотом.Мне показалось, что printf будет использовать malloc, но когда я тестировал программу с valgrind, я заметил, что вызовы printf не выделяют никакой памяти, используя malloc.Как так?Как тогда он управляет памятью?

Ответы [ 5 ]

8 голосов
/ 12 декабря 2011

Обычно единственными подпрограммами в стандарте C99, которые могут использовать malloc(), являются стандартные функции ввода / вывода (в <stdio.h>, где структура файла и используемый им буфер часто выделяются, как если бы malloc(). Некоторые из обработчиков локалей могут использовать динамическую память. Во всех других подпрограммах вообще не требуется динамическое выделение памяти.

Теперь, это официально задокументировано? Нет, я так не думаю. Не существует общего ограничения «функции в библиотеке не должны использовать malloc()». (Однако существуют ограничения для других функций - таких как strtok() и srand() и rand(); они могут не использоваться реализацией, и реализация может не использовать какие-либо другие функции, которые могут возвращать указатель в статическую область памяти.) Однако, одной из причин, почему чрезвычайно полезная функция strdup() отсутствует в стандартной библиотеке C, является (как сообщается), потому что она выделяет память. Также не совсем ясно, был ли это фактор в подпрограммах, таких как asprintf() и vasprintf() в TR 24731-2, которые не были включены в C1x, но это могло быть фактором.

5 голосов
/ 12 декабря 2011

Стандарт не предъявляет каких-либо требований к реализации, AFAIK.

Я не знаю точно, как реализован printf, но из головы не могу вспомнитьпричина, почему это должно было бы динамически распределять память.Вы всегда можете посмотреть на источник для вашей платформы.

3 голосов
/ 12 декабря 2011

Зависит от того, какой libc вы используете.Не должно быть никаких ограничений для спецификации C и вплоть до реализации.

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

Я не использовал valgrind, я не уверен, может ли он обнаружить использование _malloc_r().

2 голосов
/ 13 декабря 2011

Ни C, ни стандартные разработчики силы POSIX не используют malloc(), поэтому нет общего ответа на ваш вопрос.

Тем не менее, каждая нормальная реализация стандартной библиотеки, которая использует malloc() в одной из своих функций, будет устанавливать errno в ENOMEM, если malloc() завершится неудачей. Следовательно, вы можете извлечь из документации, использует ли библиотечная функция malloc() или нет. Точка в случае: в моей системе mmap() может использовать malloc(), поскольку mmap() может установить errno на ENOMEM.


Тем не менее, использование valgrind является плохим способом выяснить, вызывает ли конкретная функция malloc() или нет. Рассмотрим следующий фрагмент кода:

void foo(int x)
{
    if (!x) malloc(1);
}

Если вы вызываете эту функцию с аргументом, отличным от 0, valgrind не заметит, что на самом деле может вызвать malloc(). Думайте о valgrind как о виртуальной машине (поскольку это то, что она есть): она не смотрит на ваш код, она видит только то, что на самом деле машина будет выполнять.

1 голос
/ 12 декабря 2011

printf не нужно формировать всю выходную строку за один снимок, он может отправлять ее на выходной фрагмент за куском, и когда он встречает спецификатор формата, он может выводить этот фрагмент данных по мере его формирования и продолжатьс остальной частью строки.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...