Функция malloc() в библиотеке C с ПРИМЕРОМ
⚡ Умное резюме
Функция malloc() в языке C резервирует блок памяти в куче во время выполнения и возвращает указатель типа void на его первый байт, позволяя программам запрашивать хранилище, размер которого неизвестен до фактического выполнения кода.
Что такое malloc в C?
Функция malloc() отвечает за выделение памяти. Это функция, которая используется для динамического выделения блока памяти. Он резервирует пространство памяти указанного размера и возвращает нулевой указатель, указывающий на ячейку памяти. Возвращаемый указатель обычно имеет тип void. Это означает, что мы можем назначить функцию malloc любому указателю.
Синтаксис
ptr = (cast_type *) malloc (byte_size);
Здесь,
- ptr — это указатель cast_type.
- Функция malloc возвращает указатель на выделенную память размером byte_size.
Example: ptr = (int *) malloc (50)
При успешном выполнении этого оператора резервируется пространство памяти размером 50 байт. Адрес первого байта зарезервированного пространства присваивается указателю ptr типа int.
Рассмотрим еще один пример реализации malloc:
#include <stdlib.h> int main(){ int *ptr; ptr = malloc(15 * sizeof(*ptr)); /* a block of 15 integers */ if (ptr != NULL) { *(ptr + 5) = 480; /* assign 480 to sixth integer */ printf("Value of the 6th integer is %d",*(ptr + 5)); } }
Выход:
Value of the 6th integer is 480
Обратите внимание, что вместо sizeof(int) использована функция sizeof(*ptr), чтобы сделать код более устойчивым при последующем преобразовании типа объявления *ptr в другой тип данных.
Выделение может завершиться неудачей, если памяти недостаточно. В этом случае он возвращает NULL-указатель. Итак, вам следует включить код для проверки NULL-указателя.
Следует помнить, что выделенная память является непрерывной и может рассматриваться как массив. Мы можем использовать указатель Для доступа к элементам массива используются арифметические операции, а не квадратные скобки [ ]. Мы рекомендуем использовать + для обращения к элементам массива, поскольку использование инкремента ++ или += изменяет адрес, хранящийся в указателе.
Функцию Malloc можно использовать как с символьными типами данных, так и со сложными типами данных, такими как структуры.
Зачем использовать функцию malloc() в C?
Статические массивы и обычные переменные фиксируют свой размер при компиляции программы, что приводит к нерациональному использованию памяти при небольших требованиях и к полному сбою при больших. Функция malloc() решает эту проблему, запрашивая память во время выполнения, поэтому программа может задать размер буфера точно в соответствии с объемом получаемых данных. Эта гибкость во время выполнения является основой... динамическое распределение памяти в С.
Динамическое выделение памяти с помощью функции malloc() — правильный выбор в ряде распространенных ситуаций:
- Объем входных данных неизвестен до запуска программы, например, при чтении файла или предоставленного пользователем списка.
- Необходимы большие блоки данных, которые переполнили бы ограниченный стек, поскольку функция malloc() использует гораздо больший объем кучи.
- Данные должны существовать дольше, чем функция, которая их создала, поскольку память кучи сохраняется до тех пор, пока она не будет явно освобождена.
- Структуры и массивы должны увеличиваться или уменьшаться в размерах во время выполнения программы.
Поскольку зарезервированный блок возвращается в виде указателя, его можно недорого передавать между функциями без копирования базовых данных.
Как освободить память, выделенную функцией malloc()
Память, зарезервированная функцией malloc(), находится в куче и никогда не освобождается автоматически. Когда программа продолжает выделять память, не освобождая её, она постепенно потребляет всю доступную память — это дефект, известный как утечка памяти. Функция free() возвращает системе завершенный блок памяти, чтобы её можно было использовать повторно.
Функция free() принимает один аргумент — указатель, возвращенный функцией malloc(), — и освобождает весь блок памяти сразу:
int *ptr; ptr = malloc(10 * sizeof(int)); if (ptr != NULL) { /* use the allocated memory here */ free(ptr); /* release the block */ ptr = NULL; /* avoid a dangling pointer */ }
Для безопасного управления динамической памятью следуйте этим правилам:
- Вызовите функцию free() ровно один раз при каждом успешном вызове malloc(); освобождение одного и того же блока дважды приведет к неопределенному поведению.
- После освобождения памяти установите указатель в значение NULL, чтобы его нельзя было повторно использовать в качестве висячего указателя.
- Никогда не освобождайте указатель с помощью функции free(), если функция malloc() его не вернула, включая указатель, сдвинутый в результате арифметических операций с указателями.
- Перед тем как указатель выйдет из области видимости, необходимо сопоставить каждое выделение памяти с соответствующим освобождением памяти.
Keeping Сбалансированное выделение и освобождение памяти — это основная дисциплина ручного управления памятью в языке C, которая предотвращает как утечки, так и сбои, вызванные повторным использованием освобожденной памяти.
malloc() против calloc(): ключевые различия
malloc() и calloc () Обе функции резервируют память кучи, но различаются аргументами и способом обработки нового блока. Функция malloc() принимает один аргумент — общее количество байтов — и оставляет содержимое неинициализированным, поэтому блок содержит непредсказуемые мусорные значения до тех пор, пока программа не запишет в него данные. Функция calloc() принимает два аргумента — количество элементов и размер каждого из них — и обнуляет каждый байт перед возвратом указателя.
Практические различия сводятся к трем пунктам:
- Инициализация: функция calloc() обнуляет память, в то время как malloc() этого не делает, что делает malloc() немного быстрее, если значения всё равно будут перезаписаны.
- Аргументы: вы пишете malloc(n * size), но calloc(n, size) резервируете один и тот же массив.
- Пример использования: выбирайте calloc(), когда важен чистый, обнуленный блок, и malloc(), когда предпочтительнее скорость и инициализация выполняется вручную.
Обе функции объявлены в stdlib.h, обе возвращают указатель типа void или NULL в случае ошибки, и обе возвращают память с помощью одной и той же функции free().


