Dynamic Memory Allocation in C using malloc(), calloc(), free() and realloc()

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

arrays

Как вы можете видеть на изображении выше длина (размер) массива равна 9. Но что если требуется уменьшить длину, например, с 9 до 5 элементов, чтобы не расходовать память понапрасну?
Или наоборот, если массив из 9 элементов заполнен до конца, то увеличить его, например до 12?

В этом случае используется динамическое выделение памяти (Dynamic Memory Allocation).

Dynamic Memory Allocation - процедура изменяющая размер структуры данных во время выполнения программы.

C располагает для этого 4 функциями, которые подключаются заголовочным файлом <stdlib.h> и реализуют выделение памяти в С. Вот они:

Рассмотрим каждую из них подробнее:

malloc()

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

Синтаксис:

 ptr = (cast-type*) malloc(byte-size)

Например:

 ptr = (int*) malloc(5 * sizeof(int));

Т.к. размер int равен 4-м байтам,
это выражение выделит 20 байт памяти.
Указатель ptr будет содержать
первый байт выделенной области памяти.

 malloc

Если же места недостаточно, выделение завершится неудачно и будет возвращён указатель NULL.

Пример:

#include <stdio.h> 
#include <stdlib.h> 
 
int main() 
{ 
 
    // This pointer will hold the 
    // base address of the block created 
    int* ptr; 
    int n, i, sum = 0; 
 
    // Get the number of elements for the array 
    n = 5; 
    printf("Enter number of elements: %d\n", n); 
 
    // Dynamically allocate memory using malloc() 
    ptr = (int*)malloc(n * sizeof(int)); 
 
    // Check if the memory has been successfully 
    // allocated by malloc or not 
    if (ptr == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); 
    } 
    else { 
 
        // Memory has been successfully allocated 
        printf("Memory successfully allocated using malloc.\n"); 
 
        // Get the elements of the array 
        for (i = 0; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
 
        // Print the elements of the array 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
    } 
 
    return 0; 
} 

Вывод программы:

Enter number of elements: 5
Memory successfully allocated using malloc.
The elements of the array are: 1, 2, 3, 4, 5,

calloc()

“calloc” или “последовательное распределение” метод динамического выделения заданного кол-ва блоков указанного размера. При инициализации каждый блок получает значение по умолчанию - '0'.

Синтаксис:

 ptr = (cast-type*)calloc(n, element-size);

Например:

 ptr = (float*) calloc(5, sizeof(float));

Данное выражение выделяет непрерывное пространство в памяти
для 5-ти элементов, каждый из которых имеет размер 4 байта.

 calloc

Если места недостаточно, возвращается указатель NULL.

Пример:

#include <stdio.h> 
#include <stdlib.h> 
 
int main() 
{ 
 
    // This pointer will hold the 
    // base address of the block created 
    int* ptr; 
    int n, i, sum = 0; 
 
    // Get the number of elements for the array 
    n = 5; 
    printf("Enter number of elements: %d\n", n); 
 
    // Dynamically allocate memory using calloc() 
    ptr = (int*)calloc(n, sizeof(int)); 
 
    // Check if the memory has been successfully 
    // allocated by malloc or not 
    if (ptr == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); 
    } 
    else { 
 
        // Memory has been successfully allocated 
        printf("Memory successfully allocated using calloc.\n"); 
 
        // Get the elements of the array 
        for (i = 0; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
 
        // Print the elements of the array 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
    } 
 
    return 0; 
}

Вывод программы:

Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5,

free()

“free” - метод используемый для освобождения (de-allocated) памяти выделенной при помощи функций malloc и calloc, которые сами по себе не могут освободить её. Это помогает уменьшить потери памяти.

Синтаксис:

free(ptr);

 free de-allocated

Пример:

#include <stdio.h> 
#include <stdlib.h> 
 
int main() 
{ 
 
    // This pointer will hold the 
    // base address of the block created 
    int *ptr, *ptr1; 
    int n, i, sum = 0; 
 
    // Get the number of elements for the array 
    n = 5; 
    printf("Enter number of elements: %d\n", n); 
 
    // Dynamically allocate memory using malloc() 
    ptr = (int*)malloc(n * sizeof(int)); 
 
    // Dynamically allocate memory using calloc() 
    ptr1 = (int*)calloc(n, sizeof(int)); 
 
    // Check if the memory has been successfully 
    // allocated by malloc or not 
    if (ptr == NULL || ptr1 == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); 
    } 
    else { 
 
        // Memory has been successfully allocated 
        printf("Memory successfully allocated using malloc.\n"); 
 
        // Free the memory 
        free(ptr); 
        printf("Malloc Memory successfully freed.\n"); 
 
        // Memory has been successfully allocated 
        printf("\nMemory successfully allocated using calloc.\n"); 
 
        // Free the memory 
        free(ptr1); 
        printf("Calloc Memory successfully freed.\n"); 
    } 
 
    return 0; 
}

Вывод программы:

Enter number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.
Memory successfully allocated using calloc.
Calloc Memory successfully freed.

realloc()

“realloc” или “перераспределение памяти” - метод позволяющий перераспределять память. Если памяти выделенной до этого при помощи функций malloc и calloc недостаточно, при помощи realloc можно перераспределить её.

Синтаксис:

 ptr = realloc(ptr, newSize);

где ptr это перераспределяемая область с новым размером 'newSize'.

 realloc

Если же места недостаточно, указатель возвращает NULL.

Пример:

#include <stdio.h> 
#include <stdlib.h> 
 
int main() 
{ 
 
    // This pointer will hold the 
    // base address of the block created 
    int* ptr; 
    int n, i, sum = 0; 
 
    // Get the number of elements for the array 
    n = 5; 
    printf("Enter number of elements: %d\n", n); 
 
    // Dynamically allocate memory using calloc() 
    ptr = (int*)calloc(n, sizeof(int)); 
 
    // Check if the memory has been successfully 
    // allocated by malloc or not 
    if (ptr == NULL) { 
        printf("Memory not allocated.\n"); 
        exit(0); 
    } 
    else { 
 
        // Memory has been successfully allocated 
        printf("Memory successfully allocated using calloc.\n"); 
 
        // Get the elements of the array 
        for (i = 0; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
 
        // Print the elements of the array 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
 
        // Get the new size for the array 
        n = 10; 
        printf("\n\nEnter the new size of the array: %d\n", n); 
 
        // Dynamically re-allocate memory using realloc() 
        ptr = realloc(ptr, n * sizeof(int)); 
 
        // Memory has been successfully allocated 
        printf("Memory successfully re-allocated using realloc.\n"); 
 
        // Get the new elements of the array 
        for (i = 5; i < n; ++i) { 
            ptr[i] = i + 1; 
        } 
 
        // Print the elements of the array 
        printf("The elements of the array are: "); 
        for (i = 0; i < n; ++i) { 
            printf("%d, ", ptr[i]); 
        } 
 
        free(ptr); 
    } 
 
    return 0; 
}

Вывод:

Enter number of elements: 5
Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5, 

Enter the new size of the array: 10
Memory successfully re-allocated using realloc.
The elements of the array are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
Только авторизованные участники могут оставлять комментарии.
  • blog/dynamic_memory_alloc_in_c.txt
  • Последние изменения: 2019/05/29