Dynamic Memory Allocation in C (malloc, calloc, free)


Dynamic memory allocation allows a program to request memory space during runtime. It is especially useful in cases where the memory requirements are not known until the program is running. C provides a few standard library functions to perform dynamic memory allocation, specifically malloc, calloc, and free.

malloc (Memory Allocation)

malloc stands for "memory allocation" and is used to allocate a specific number of bytes in memory. It returns a pointer to the beginning of the allocated memory block. If the allocation fails, malloc returns NULL.

Syntax:

void* malloc(size_t size);

The size parameter represents the number of bytes to allocate. Since malloc returns a void* pointer, it needs to be cast to the appropriate type.

Example of malloc:

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

    int main() {
        int *arr;
        int n = 5;

        // Allocate memory for an array of 5 integers
        arr = (int*)malloc(n * sizeof(int));

        // Check if memory allocation succeeded
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }

        // Initialize and print elements
        for (int i = 0; i < n; i++) {
            arr[i] = i + 1;
            printf("%d ", arr[i]);
        }

        // Free the allocated memory
        free(arr);

        return 0;
    }
        

This program allocates memory for an array of five integers using malloc. If allocation fails, arr will be NULL. After initializing and printing the elements, free(arr) is used to release the memory.

calloc (Contiguous Allocation)

calloc stands for "contiguous allocation" and is used to allocate memory for an array of elements. It initializes all allocated bytes to zero, which makes it different from malloc.

Syntax:

void* calloc(size_t num, size_t size);

The num parameter represents the number of elements, and size represents the size of each element.

Example of calloc:

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

    int main() {
        int *arr;
        int n = 5;

        // Allocate memory for an array of 5 integers using calloc
        arr = (int*)calloc(n, sizeof(int));

        // Check if memory allocation succeeded
        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }

        // Print initialized elements (all should be zero)
        for (int i = 0; i < n; i++) {
            printf("%d ", arr[i]);
        }

        // Free the allocated memory
        free(arr);

        return 0;
    }
        

In this example, memory is allocated for an array of five integers, and each element is initialized to zero by default. The memory is freed after it is used with free(arr).

free (Deallocate Memory)

The free function is used to release dynamically allocated memory back to the system. Failing to free memory after it is no longer needed can cause memory leaks, which may degrade system performance over time.

Syntax:

void free(void* ptr);

The ptr parameter is a pointer to the memory to be freed. After calling free, the pointer ptr should not be used again until it is reallocated.

Example of free:

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

    int main() {
        int *arr;
        int n = 5;

        // Allocate memory for an array of 5 integers
        arr = (int*)malloc(n * sizeof(int));

        if (arr == NULL) {
            printf("Memory allocation failed\n");
            return 1;
        }

        // Initialize and print elements
        for (int i = 0; i < n; i++) {
            arr[i] = i + 1;
            printf("%d ", arr[i]);
        }

        // Free the allocated memory
        free(arr);

        // Attempting to access arr after freeing is undefined behavior
        return 0;
    }
        

In this example, free(arr) is used to release the memory allocated by malloc. Accessing the array after calling free leads to undefined behavior.

Key Points to Remember

  • malloc allocates uninitialized memory, while calloc allocates zero-initialized memory.
  • Always check if memory allocation was successful by verifying that the pointer is not NULL.
  • Free allocated memory using free to avoid memory leaks.
  • Accessing memory after calling free on it is undefined behavior.

Conclusion

Dynamic memory allocation provides flexibility in managing memory requirements during runtime. Functions like malloc, calloc, and free allow programmers to allocate, initialize, and deallocate memory in the heap. Proper usage of these functions is essential for writing efficient and robust C programs.






Advertisement