Scroll to navigation

MALLOC(3) Руководство программиста Linux MALLOC(3)

ИМЯ

malloc, free, calloc, realloc, reallocarray - allocate and free dynamic memory

СИНТАКСИС

#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void *reallocarray(void *ptr, size_t nmemb, size_t size);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

reallocarray():
Since glibc 2.29:
_DEFAULT_SOURCE
Glibc 2.28 and earlier:
_GNU_SOURCE

ОПИСАНИЕ

Функция malloc() распределяет size байтов и возвращает указатель на распределённую память. Память при этом не инициализируется. Если значение size равно 0, то malloc() возвращает или NULL, или уникальный указатель, который можно без опасений передавать free().

Функция free() освобождает место в памяти, указанное в ptr, которое должно быть получено ранее вызовом функции malloc(), calloc() или realloc(). Иначе (или если вызов free(ptr) уже выполнялся) дальнейшее поведение не определено. Если значение ptr равно NULL, то не выполняется никаких действий.

Функция сalloc() распределяет память для массива размером nmemb элементов по size байтов каждый и возвращает указатель на распределённую память. Данные в выделенной памяти при этом обнуляются. Если значение nmemb или size равно 0, то calloc() возвращает NULL или уникальный указатель, который можно без опасений передавать free(). Если перемножение nmemb и size приводит к целочисленному переполнению, то calloc() возвращает ошибку. Это отличает её от malloc(), которая не обнаруживает целочисленное переполнение и возвращает блок памяти неправильного размера:


malloc(nmemb * size);

Функция realloc() меняет размер блока памяти, на который указывает ptr, на размер, равный size байт. Содержимое памяти не будет изменено от начала области в пределах наименьшего из старого и нового размеров. Если новый размер больше старого, то добавленная память не будет инициализирована. Если значение ptr равно NULL, то вызов эквивалентен malloc(size) для всех значений size; если значение size равно нулю и ptr не равно NULL, то вызов эквивалентен free(ptr). Если только значение ptr не равно NULL, то должно быть возвращено ранее полученное значение от malloc(), calloc() или realloc(). Если область была перемещена, то выполняется free(ptr).

Функция reallocarray() изменяет размер блока памяти, на который указывает ptr, таким образом, чтобы он смог вместить массив из nmemb элементов, каждый из которых занимает size байт. Она эквивалентна вызову



realloc(ptr, nmemb * size);

Однако в отличие от вызова realloc(), функция reallocarray() безопасно завершается ошибкой в случае возникновения переполнения умножения. Если это происходит, то reallocarray() возвращает NULL, присваивает errno значение ENOMEM и оставляет первоначальный блок памяти в неизменном виде.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Функции malloc() и calloc() возвращают указатель на распределённую память, выровненную должным образом для любого встроенного типа. При ошибке возвращается NULL. Значение NULL также может быть получено при успешной работе вызова malloc(), если значение size равно нулю, или calloc() — если значение nmemb или size равно нулю.

Функция free() ничего не возвращает.

The realloc() function returns a pointer to the newly allocated memory, which is suitably aligned for any built-in type, or NULL if the request failed. The returned pointer may be the same as ptr if the allocation was not moved (e.g., there was room to expand the allocation in-place), or different from ptr if the allocation was moved to a new address. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails, the original block is left untouched; it is not freed or moved.

При успешном выполнении функция reallocarray() возвращает указатель на новую выделенную память. При ошибке возвращается NULL, а первоначальный блок памяти не изменяется.

ОШИБКИ

Функции calloc(), malloc(), realloc() и reallocarray() могут завершаться со следующей ошибкой:

Не хватает памяти. Вероятно приложение достигнут лимит RLIMIT_AS или RLIMIT_DATA, описанный в getrlimit(2).

ВЕРСИИ

reallocarray() first appeared in glibc in version 2.26.

АТРИБУТЫ

Описание терминов данного раздела смотрите в attributes(7).

Интерфейс Атрибут Значение
malloc(), free(), calloc(), realloc() Безвредность в нитях MT-Safe

СООТВЕТСТВИЕ СТАНДАРТАМ

malloc(), free(), calloc(), realloc(): POSIX.1-2001, POSIX.1-2008, C89, C99.

Функция reallocarray() является нестандартным расширением, впервые появилась в OpenBSD 5.6 и FreeBSD 11.0.

ЗАМЕЧАНИЯ

По умолчанию, Linux придерживается оптимистичной стратегии распределения памяти. Это означает, что когда malloc() возвращает значение не NULL, то нет никаких гарантий, что память в действительности доступна. Если обнаружится, что системе не хватает памяти, то один или несколько процессов будут завершены OOM. Дополнительную информацию можно получить из описания /proc/sys/vm/overcommit_memory и /proc/sys/vm/oom_adj в proc(5) и файле из исходного кода ядра Linux Documentation/vm/overcommit-accounting.rst.

Обычно, malloc() выделяет память из кучи и подгоняет размер кучи соответствующим образом с помощью sbrk(2). Если выделяемый блок памяти больше чем MMAP_THRESHOLD байт, то реализация malloc() в glibc выделяет память с помощью mmap(2) в виде частного анонимного отображения. По умолчанию, значение MMAP_THRESHOLD равно 128 КБ, но его можно изменить с помощью mallopt(3). До Linux 4.7 на выделения, выполняемые с помощью mmap(2), не влияет ограничитель ресурса RLIMIT_DATA; начиная с Linux 4.7 это ограничение также применяется к выделениям, созданным с помощью mmap(2).

Внутри данных функций для защиты от повреждений выделяемых структур данных управления памятью, используются мьютексы. В многонитевых приложениях, в которых нити одновременно выделяют и освобождают память, может возникнуть конфликт за обладание этими мьютексами. Чтобы расширить обработку выделения памяти в многонитевых приложениях библиотека glibc создаёт дополнительные области выделения памяти (memory allocation arenas), если обнаруживается конфликт. Каждая область представляет собой большой кусок памяти, который внутренне выделен системой (с помощью brk(2) или mmap(2)) и управляется своими собственными мьютексами.

Стандарт SUSv2 требует, чтобы функции malloc(), calloc() и realloc() при ошибках присваивали значение ENOMEM переменной errno. Glibc допускает, что это уже реализовано (и версии glibc этих функций делают это); если вы используете свою реализацию функции malloc, которая не изменяет errno, то некоторые функции библиотеки могут закончить работу с ошибкой без указания причины в errno.

Аварийные ситуации в malloc(), calloc(), realloc() или free() почти всегда связаны с повреждением кучи, например, с переполнением больших распределённых участков памяти или освобождением одного и того же указателя дважды.

Реализация malloc() настраивается с помощью переменных окружения; подробности смотрите в mallopt(3).

СМ. ТАКЖЕ

valgrind(1), brk(2), mmap(2), alloca(3), malloc_get_state(3), malloc_info(3), malloc_trim(3), malloc_usable_size(3), mallopt(3), mcheck(3), mtrace(3), posix_memalign(3)

Информацию о реализации в библиотеке GNU C смотрите в https://sourceware.org/glibc/wiki/MallocInternals.

ЗАМЕЧАНИЯ

Эта страница является частью проекта Linux man-pages версии 5.10. Описание проекта, информацию об ошибках и последнюю версию этой страницы можно найти по адресу https://www.kernel.org/doc/man-pages/.

ПЕРЕВОД

Русский перевод этой страницы руководства был сделан aereiae <aereiae@gmail.com>, Alexey <a.chepugov@gmail.com>, Azamat Hackimov <azamat.hackimov@gmail.com>, Dmitriy S. Seregin <dseregin@59.ru>, Dmitry Bolkhovskikh <d20052005@yandex.ru>, ITriskTI <ITriskTI@gmail.com>, Max Is <ismax799@gmail.com>, Yuri Kozlov <yuray@komyakino.ru>, Иван Павлов <pavia00@gmail.com> и Малянов Евгений Викторович <maljanow@outlook.com>

Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

9 июня 2020 г. GNU