Динамическое выделение памяти в C: malloc(), calloc()
⚡ Умное резюме
Динамическое выделение памяти в C резервирует и освобождает память кучи во время выполнения с помощью функций malloc(), calloc(), realloc() и free() из библиотеки stdlib.h, позволяя программам гибко определять размер массивов и структур, когда требования неизвестны до начала выполнения.

Как работает управление памятью в C?
При объявлении переменной с использованием базового типа данных компилятор C автоматически выделяет для неё память в пуле памяти, называемом стеком.
Например, переменная типа float обычно занимает 4 байта (в зависимости от платформы) при объявлении. Мы можем проверить эту информацию, используя оператор sizeof, как показано в примере ниже.
#include <stdio.h> int main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Выходной сигнал будет:
The size of float is 4 bytes
Также массив заданного размера размещается в смежных блоках памяти, каждый блок имеет размер для одного элемента:
#include <stdio.h> int main() { float arr[10]; printf("The size of the float array with 10 element is %d", sizeof(arr)); return 0;}
Результат:
The size of the float array with 10 element is 40
Как уже было изучено, при объявлении базового типа данных или массива управление памятью происходит автоматически. Однако в языке C существует процесс выделения памяти, который позволяет реализовать программу, в которой размер массива не определен до момента запуска программы (во время выполнения). Этот процесс называется «динамическим выделением памяти».
Динамическое распределение памяти в C
Динамическое выделение памяти — это ручное выделение и освобождение памяти в соответствии с потребностями вашего программирования. Динамическая память управляется и предоставляется с помощью указателей, которые указывают на вновь выделенное пространство памяти в области, которую мы называем кучей.
Теперь вы можете без проблем создавать и уничтожать массив элементов динамически во время выполнения. Подводя итог, можно сказать, что автоматическое управление памятью использует стек, а динамическое распределение памяти C использует кучу.
библиотека имеет функции, отвечающие за динамическое управление памятью.
| Функция | Цель |
|---|---|
| таНос () | Выделяет память запрошенного размера и возвращает указатель на первый байт выделенное пространство. |
| calloc () | Выделяет место для элементов массива. Инициализирует элементы нулями и возвращает указатель на память. |
| realloc () | Он используется для изменения размера ранее выделенного пространства памяти. |
| Бесплатно() | Освобождает или очищает ранее выделенное пространство памяти. |
Давайте обсудим вышеуказанные функции с их применением.
Функция malloc() в C
Функция C malloc() обозначает распределение памяти. Это функция, которая используется для динамического выделения блока памяти. Он резервирует пространство памяти указанного размера и возвращает нулевой указатель, указывающий на ячейку памяти. Возвращаемый указатель обычно имеет тип void. Это означает, что мы можем назначить функцию C malloc() любому указателю.
Синтаксис функции malloc():
ptr = (cast_type *) malloc (byte_size);
Здесь,
- ptr — это указатель cast_type.
- Функция C malloc() возвращает указатель на выделенную память размером byte_size.
Пример функции malloc():
Example: ptr = (int *) malloc (50)
При успешном выполнении этого оператора резервируется пространство памяти размером 50 байт. Адрес первого байта зарезервированного пространства присваивается указателю ptr типа int.
Рассмотрим другой пример:
#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() также можно использовать с символьным типом данных, а также со сложными типами данных, такими как структуры.
функция free() в C
Память для переменные автоматически освобождается во время компиляции. При динамическом распределении памяти необходимо явно освобождать память. Если этого не сделать, вы можете столкнуться с ошибкой нехватки памяти.
Функция free() вызывается для освобождения/освобождения памяти в языке C. Освобождая память в программе, вы освобождаете больше памяти для последующего использования.
Например:
#include <stdio.h> int main() { int* ptr = malloc(10 * sizeof(*ptr)); if (ptr != NULL){ *(ptr + 2) = 50; printf("Value of the 2nd integer is %d",*(ptr + 2)); } free(ptr); }
Выход:
Value of the 2nd integer is 50
функция calloc() в C
Функция C calloc() означает непрерывное выделение. Эта функция используется для выделения нескольких блоков памяти. Это функция динамического выделения памяти, которая используется для выделения памяти для сложных структур данных, таких как массивы и структуры.
Функция Malloc() используется для выделения одного блока памяти, а функция calloc() в C используется для выделения нескольких блоков памяти. Каждый блок, выделенный функцией calloc(), имеет одинаковый размер.
Синтаксис функции calloc():
ptr = (cast_type *) calloc (n, size);
Приведенный выше оператор используется для выделения n блоков памяти одинакового размера.
После выделения пространства памяти все байты инициализируются нулями.
Возвращается указатель, который в данный момент находится на первом байте выделенного пространства памяти.
Всякий раз, когда возникает ошибка при выделении памяти, например нехватка памяти, возвращается нулевой указатель.
Пример вызова():
Программа ниже вычисляет сумму арифметической последовательности.
#include <stdio.h> int main() { int i, * ptr, sum = 0; ptr = calloc(10, sizeof(int)); if (ptr == NULL) { printf("Error! memory not allocated."); exit(0); } printf("Building and calculating the sequence sum of the first 10 terms \ n "); for (i = 0; i < 10; ++i) { * (ptr + i) = i; sum += * (ptr + i); } printf("Sum = %d", sum); free(ptr); return 0; }
Результат:
Building and calculating the sequence sum of the first 10 terms
Sum = 45
calloc() и malloc(): ключевые различия
Ниже приводится ключевое различие между malloc() против calloc() в C:
Функция calloc() обычно более удобна и эффективна, чем функция malloc(). Хотя обе функции используются для выделения пространства памяти, calloc() может выделять несколько блоков одновременно. Вам не нужно каждый раз запрашивать блок памяти. Функция calloc() используется в сложных структурах данных, требующих большего объема памяти.
Блок памяти, выделенный вызовом calloc() в C, всегда инициализируется нулем, тогда как в функции malloc() в C он всегда содержит мусорное значение.
Функция realloc() в C
С помощью функции realloc() в языке C можно увеличить объем уже выделенной памяти. Она расширяет текущий блок, оставляя при этом исходное содержимое неизменным. realloc() в языке C означает перераспределение памяти.
Realloc() также можно использовать для уменьшения размера ранее выделенной памяти.
Синтаксис функции realloc():
ptr = realloc (ptr,newsize);
Приведенный выше оператор выделяет новое пространство памяти с указанным размером в переменной newsize. После выполнения функции указатель вернется на первый байт блока памяти. Новый размер может быть больше или меньше предыдущего размера памяти. Мы не можем быть уверены, что новый выделенный блок будет указывать на то же место, что и предыдущий блок памяти. Эта функция скопирует все предыдущие данные в новый регион. Это гарантирует, что данные останутся в безопасности.
Пример realloc():
#include <stdio.h> int main () { char *ptr; ptr = (char *) malloc(10); strcpy(ptr, "Programming"); printf(" %s, Address = %u\n", ptr, ptr); ptr = (char *) realloc(ptr, 20); //ptr is reallocated with new size strcat(ptr, " In 'C'"); printf(" %s, Address = %u\n", ptr, ptr); free(ptr); return 0; }
Всякий раз, когда функция realloc() в C приводит к неудачной операции, она возвращает нулевой указатель, а предыдущие данные также освобождаются.
Динамические массивы в C
Динамический массив в C позволяет увеличивать количество элементов по мере необходимости. Динамические массивы C широко используются в алгоритмах информатики.
В следующей программе мы создали и изменили размер динамического массива в C
#include <stdio.h> int main() { int * arr_dynamic = NULL; int elements = 2, i; arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocks for (i = 0; i < elements; i++) arr_dynamic[i] = i; for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]); elements = 4; arr_dynamic = realloc(arr_dynamic, elements * sizeof(int)); //reallocate 4 elements printf("After realloc\n"); for (i = 2; i < elements; i++) arr_dynamic[i] = i; for (i = 0; i < elements; i++) printf("arr_dynamic[%d]=%d\n", i, arr_dynamic[i]); free(arr_dynamic); }
Результат программы динамического массива C на экране:
arr_dynamic[0]=0 arr_dynamic[1]=1 After realloc arr_dynamic[0]=0 arr_dynamic[1]=1 arr_dynamic[2]=2 arr_dynamic[3]=3

