Dynamic Memory Allocation in C

Dynamic Memory Allocation in C. Dynamic Memory Allocation in C Tutorial. Learn Dynamic Memory Allocation in C
Dynamic Memory Allocation in C.

What is Dynamic Memory Allocation in C ?

Dynamic memory allocation in C refers to the process of allocating memory during runtime, allowing the program to request and release memory as needed. This is done using functions provided by the C standard library, such as malloc, calloc, realloc, and free.

Here’s a table summarizing the different types of dynamic memory allocation:

Sr. No.Memory Allocation TypeInformationAdditional Information
1mallocAllocates a block of memoryThe allocated memory is not initialized
2callocAllocates and initializes a block of memoryMemory is initialized to zero
3reallocResizes a previously allocated block of memoryCan be used to increase or decrease the size of the memory block
4freeReleases the allocated memoryShould always be called to avoid memory leaks

1. malloc in C

malloc stands for “memory allocation.” It is used to allocate a specified amount of memory in bytes.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(5 * sizeof(int));
    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Access and modify allocated memory
    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1;
    }

    // Print the allocated memory
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr);
    return 0;
}

Output:

1 2 3 4 5

Explanation:

The malloc function is used to allocate a specified amount of memory in bytes. In this example, we allocate memory for an array of 5 integers.

Code Explanation:

  • We include the necessary header files, stdio.h for input/output operations and stdlib.h for memory allocation functions.
  • Inside the main function, we declare a pointer ptr of type int*.
  • We use malloc to allocate memory for 5 integers (5 * sizeof(int) bytes) and assign the returned memory address to ptr.
  • We check if the memory allocation was successful by comparing ptr with NULL. If ptr is NULL, it means the allocation failed, and we print an error message and return from the program.
  • We use a loop to access and modify the allocated memory, assigning values 1 to 5 to each element of the array.
  • Finally, we print the contents of the allocated memory using another loop.
  • We release the allocated memory using free(ptr) to avoid memory leaks.

2. calloc in C

calloc stands for “contiguous allocation.” It is used to allocate memory and initialize all the bytes to zero.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)calloc(5, sizeof(int));
    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Print the allocated memory
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr);
    return 0;
}

Output:

0 0 0 0 0

Explanation:

The calloc function is used to allocate memory and initialize all the bytes to zero. In this example, we allocate memory for an array of 5 integers.

Code Explanation:

  • We include the necessary header files, stdio.h for input/output operations and stdlib.h for memory allocation functions.
  • Inside the main function, we declare a pointer ptr of type int*.
  • We use calloc to allocate memory for 5 integers (5 * sizeof(int) bytes) and assign the returned memory address to ptr.
  • We check if the memory allocation was successful by comparing ptr with NULL. If ptr is NULL, it means the allocation failed, and we print an error message and return from the program.
  • We print the contents of the allocated memory using a loop. Since calloc initializes the memory to zero, all the elements of the array will be printed as 0.
  • We release the allocated memory using free(ptr) to avoid memory leaks.

3. realloc in C

realloc stands for “reallocate.” It is used to resize a previously allocated block of memory.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(5 * sizeof(int));
    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Access and modify initial memory
    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1;
    }

    // Resize the memory to hold 8 integers
    ptr = (int*)realloc(ptr, 8 * sizeof(int));

    // Access and modify the resized memory
    for (int i = 5; i < 8; i++) {
        ptr[i] = i + 1;
    }

    // Print the allocated memory
    for (int i = 0; i < 8; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr);
    return 0;
}

Output:

1 2 3 4 5 6 7 8

Explanation:

The realloc function is used to resize a previously allocated block of memory. In this example, we allocate memory for 5 integers and then resize it to hold 8 integers.

Code Explanation:

  • We include the necessary header files, stdio.h for input/output operations and stdlib.h for memory allocation functions.
  • Inside the main function, we declare a pointer ptr of type int*.
  • We use malloc to allocate memory for 5 integers (5 * sizeof(int) bytes) and assign the returned memory address to ptr.
  • We check if the memory allocation was successful by comparing ptr with NULL. If ptr is NULL, it means the allocation failed, and we print an error message and return from the program.
  • We use a loop to access and modify the initial allocated memory, assigning values 1 to 5 to each element of the array.
  • We use realloc to resize the memory block pointed to by ptr to hold 8 integers (8 * sizeof(int) bytes). The ptr is updated with the new memory address if the reallocation is successful.
  • We use another loop to access and modify the resized memory, assigning values 6 to 8 to the additional elements of the array.
  • Finally, we print the contents of the allocated memory using a loop.
  • We release the allocated memory using free(ptr) to avoid memory leaks.

4. free in C

free is used to release the memory previously allocated using malloc, calloc, or realloc. It is important to free memory to avoid memory leaks.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int* ptr = (int*)malloc(5 * sizeof(int));
    if (ptr == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Access and modify allocated memory
    for (int i = 0; i < 5; i++) {
        ptr[i] = i + 1;
    }

    // Print the allocated memory
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]);
    }

    free(ptr); // Release the allocated memory

    return 0;
}

Output:

1 2 3 4 5

Explanation:

The free function is used to release the memory previously allocated using malloc, calloc, or realloc. It is important to free memory to avoid memory leaks.

Code Explanation:

  • We include the necessary header files, stdio.h for input/output operations and stdlib.h for memory allocation functions.
  • Inside the main function, we declare a pointer ptr of type int*.
  • We use malloc to allocate memory for 5 integers (5 * sizeof(int) bytes) and assign the returned memory address to ptr.
  • We check if the memory allocation was successful by comparing ptr with NULL. If ptr is NULL, it means the allocation failed, and we print an error message and return from the program.
  • We use a loop to access and modify the allocated memory, assigning values 1 to 5 to each element of the array.
  • Finally, we print the contents of the allocated memory using a loop.
  • We release the allocated memory using free(ptr) to avoid memory leaks.

Complex example of dynamic memory allocation in C

The example below demonstrates how dynamic memory allocation can be used to create a flexible and scalable solution for managing employee data. The program allows the user to input any number of employees and stores their information dynamically.

Example:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int id;
    char name[50];
    float salary;
} Employee;

int main() {
    int numEmployees;
    printf("Enter the number of employees: ");
    scanf("%d", &numEmployees);

    // Dynamically allocate memory for an array of Employee structs
    Employee* employees = (Employee*)malloc(numEmployees * sizeof(Employee));
    if (employees == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    }

    // Read employee details from the user
    for (int i = 0; i < numEmployees; i++) {
        printf("\nEnter details for Employee %d:\n", i + 1);
        printf("ID: ");
        scanf("%d", &(employees[i].id));
        printf("Name: ");
        scanf("%s", employees[i].name);
        printf("Salary: ");
        scanf("%f", &(employees[i].salary));
    }

    // Print the employee details
    printf("\nEmployee Details:\n");
    for (int i = 0; i < numEmployees; i++) {
        printf("ID: %d, Name: %s, Salary: %.2f\n",
               employees[i].id, employees[i].name, employees[i].salary);
    }

    // Free the allocated memory
    free(employees);

    return 0;
}

Output:

Enter the number of employees: 2
Enter details for Employee 1:
ID: 301
Name: Jigglypuff
Salary: 4
Enter details for Employee 2:
ID: 302
Name: Dragonite
Salary: 6
Employee Details:
ID: 301, Name: Jigglypuff, Salary: 4.00
ID: 302, Name: Dragonite, Salary: 6.00

Explanation:

  • We include the necessary header files, stdio.h for input/output operations and stdlib.h for memory allocation functions.
  • We define a struct called Employee to represent the information of an employee.
  • Inside the main function, we declare a variable numEmployees to store the number of employees to be entered by the user.
  • We prompt the user to enter the number of employees using printf and read the input using scanf.
  • We use malloc to dynamically allocate memory for an array of Employee structs, based on the number of employees entered by the user.
  • We check if the memory allocation was successful by comparing employees with NULL. If employees is NULL, it means the allocation failed, and we print an error message and return from the program.
  • We use a loop to read the details of each employee from the user, including their ID, name, and salary. The data is stored in the dynamically allocated memory.
  • After reading all the employee details, we use another loop to print the details of each employee.
  • Finally, we free the allocated memory using free(employees) to ensure proper deallocation and prevent memory leaks.

More: