Прежде чем вы изучите распределение динамической памяти C, давайте разберемся:
Как работает управление памятью в C?
Когда вы объявляете переменную с использованием базового типа данных, компилятор C автоматически выделяет пространство памяти для переменной в пуле памяти, называемом стеком .
Например, переменная с плавающей запятой обычно занимает 4 байта (в зависимости от платформы) при ее объявлении. Мы можем проверить эту информацию с помощью оператора sizeof, как показано в примере ниже.
#includeint main() { float x; printf("The size of float is %d bytes", sizeof(x)); return 0;}
Результат будет:
The size of float is 4 bytes
Также массив с указанным размером выделяется в непрерывных блоках памяти, каждый блок имеет размер для одного элемента:
#includeint 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
- C malloc (), функция
- Функция free ()
- C calloc (), функция
- calloc () против malloc (): основные различия
- Функция C realloc ()
- Динамические массивы
Распределение динамической памяти в C
Динамическое выделение памяти - это ручное выделение и освобождение памяти в соответствии с вашими программными потребностями. Динамическая память управляется и обслуживается указателями, указывающими на вновь выделенное пространство памяти в области, которую мы называем кучей.
Теперь вы можете без проблем создавать и уничтожать массив элементов динамически во время выполнения. Подводя итог, автоматическое управление памятью использует стек, а распределение динамической памяти C использует кучу.
В библиотеке
Функция | Цель |
malloc () | Выделяет память запрошенного размера и возвращает указатель на первый байт выделенного пространства. |
calloc () | Выделяет пространство для элементов массива. Инициализирует элементы до нуля и возвращает указатель на память. |
realloc () | Он используется для изменения размера ранее выделенного пространства памяти. |
Свободный() | Освобождает или очищает ранее выделенное пространство памяти. |
Давайте обсудим вышеперечисленные функции с их применением.
C malloc (), функция
Функция 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.
Рассмотрим другой пример:
#includeint 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 (* ptr) использовался вместо sizeof (int) , чтобы сделать код более надежным, когда объявление * ptr приводится к другому типу данных позже.
- Выделение может завершиться неудачно, если памяти недостаточно. В этом случае он возвращает указатель NULL. Итак, вы должны включить код для проверки указателя NULL.
- Имейте в виду, что выделенная память непрерывна и может рассматриваться как массив. Мы можем использовать арифметику указателей для доступа к элементам массива, а не использовать квадратные скобки []. Мы советуем использовать + для ссылки на элементы массива, потому что использование приращения ++ или + = изменяет адрес, хранящийся в указателе.
Функцию Malloc () также можно использовать с символьным типом данных, а также со сложными типами данных, такими как структуры.
Функция free ()
Память для переменных автоматически освобождается во время компиляции. При динамическом распределении памяти вы должны явно освободить память. Если этого не сделать, вы можете столкнуться с ошибкой нехватки памяти.
Функция free () вызывается для освобождения / освобождения памяти в C. Освобождая память в вашей программе, вы делаете больше доступной для использования позже.
Например:
#includeint 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
C calloc (), функция
Функция C calloc () означает непрерывное выделение памяти. Эта функция используется для выделения нескольких блоков памяти. Это функция динамического распределения памяти, которая используется для выделения памяти сложным структурам данных, таким как массивы и структуры.
Функция Malloc () используется для выделения одного блока пространства памяти, в то время как calloc () в C используется для выделения нескольких блоков пространства памяти. Каждый блок, выделенный функцией calloc (), имеет одинаковый размер.
Синтаксис функции calloc ():
ptr = (cast_type *) calloc (n, size);
- Вышеупомянутый оператор используется для выделения n блоков памяти одинакового размера.
- После выделения пространства памяти все байты инициализируются нулями.
- Возвращается указатель, который в настоящий момент находится на первом байте выделенного пространства памяти.
Каждый раз, когда возникает ошибка выделения пространства памяти, например нехватка памяти, возвращается нулевой указатель.
Пример calloc ():
Программа ниже вычисляет сумму арифметической последовательности.
#includeint 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 termsSum = 45
calloc () против malloc (): основные различия
Ниже приводится ключевое различие между malloc () и calloc () в C:
Функция calloc () обычно более удобна и эффективна, чем функция malloc (). Хотя обе функции используются для выделения пространства памяти, calloc () может одновременно выделять несколько блоков. Вам не нужно каждый раз запрашивать блок памяти. Функция calloc () используется в сложных структурах данных, требующих большего объема памяти.
Блок памяти, выделенный функцией calloc () в C, всегда инициализируется нулем, в то время как в функции malloc () в C он всегда содержит значение мусора.
Функция C realloc ()
Используя функцию C realloc () , вы можете добавить больший объем памяти к уже выделенной памяти. Он расширяет текущий блок, оставляя исходное содержимое как есть. realloc () в C означает перераспределение памяти.
realloc () также можно использовать для уменьшения размера ранее выделенной памяти.
Синтаксис функции realloc ():
ptr = realloc (ptr,newsize);
Вышеупомянутый оператор выделяет новое пространство памяти с указанным размером в переменной newsize. После выполнения функции указатель будет возвращен на первый байт блока памяти. Новый размер может быть больше или меньше предыдущего размера памяти. Мы не можем быть уверены, что вновь выделенный блок будет указывать на то же место, что и предыдущий блок памяти. Эта функция скопирует все предыдущие данные в новый регион. Это гарантирует, что данные останутся в безопасности.
Пример realloc ():
#includeint 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 sizestrcat(ptr, " In 'C'");printf(" %s, Address = %u\n", ptr, ptr);free(ptr);return 0;}
Каждый раз, когда realloc () в C приводит к неудачной операции, он возвращает нулевой указатель, и предыдущие данные также освобождаются.
Динамические массивы в C
Динамический массив в C позволяет увеличивать количество элементов по мере необходимости. C Динамический массив широко используется в алгоритмах информатики.
В следующей программе мы создали и изменили размер динамического массива на языке C
#includeint main() {int * arr_dynamic = NULL;int elements = 2, i;arr_dynamic = calloc(elements, sizeof(int)); //Array with 2 integer blocksfor (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 elementsprintf("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 Dynamic array на экране:
arr_dynamic[0]=0arr_dynamic[1]=1After reallocarr_dynamic[0]=0arr_dynamic[1]=1arr_dynamic[2]=2arr_dynamic[3]=3
Резюме
- Мы можем динамически управлять памятью, создавая блоки памяти по мере необходимости в куче.
- В C Dynamic Memory Allocation память выделяется во время выполнения.
- Динамическое выделение памяти позволяет манипулировать строками и массивами, размер которых является гибким и может быть изменен в любое время в вашей программе.
- Это требуется, когда вы не знаете, сколько памяти будет занимать конкретная структура.
- Malloc () в C - это функция динамического распределения памяти, которая обозначает выделение памяти, при котором блоки памяти определенного размера инициализируются значением мусора.
- Calloc () в C - это функция непрерывного распределения памяти, которая выделяет несколько блоков памяти за раз, инициализированный значением 0
- Realloc () в C используется для перераспределения памяти в соответствии с указанным размером.
- Функция Free () используется для очистки динамически выделяемой памяти.