Dynamic Arrays in C



An array in C is normally static in nature. We need to give it a fixed size when it is initialized and we cannot change the size of the array after its declaration. It may sometimes cause errors because we may encounter a scenario where our array does not have enough space left for the required elements or we allotted more than required memory leading to memory wastage. To overcome this issue, we use dynamic arrays in C programming. In this chapter, we will explain in detail how dynamic arrays work in C programming.

What are Dynamic Arrays?

A dynamic array is a type of array which allocates memory at runtime, and its size can be changed later on in the program.

Following are the functions to create a dynamic array in C programming language −

  • malloc() Function
  • calloc() Function
  • realloc() Function

Read this chapter to learn how to use these functions to creating dynamic arrays.

Dynamic Array Using malloc() Function

The malloc function (memory allocation) in C is used to dynamically allocate a single large block of memory of the specified size. It returns a pointer of type void*, which can be typecast to a pointer of any data type. The malloc function in C is defined in the <stdlib.h> header file.

Following is the syntax of malloc() function

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

We can use this function to create a dynamic array in C by simply allocating a memory block of the required size and typecasting the returned void pointer to the required type. For example, let’s create a dynamic array of type int with 100 elements.

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

Example: Creating a Dynamic Array using malloc Function

In this C program, we create a dynamic array using the malloc() function −

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

int main() {
    int* ptr;
    int n;

    printf("Enter size of elements: ");
    scanf("%d", &n);

    // Memory allocated dynamically using malloc()
    ptr = (int*)malloc(n * sizeof(int));

    // Checking for memory allocation
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
    } else {
        printf("Memory successfully allocated using malloc.\n");

        // Assigning values
        for (int i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }

        // Printing values
        printf("The elements of the array are: ");
        for (int j = 0; j < n; ++j) {
            printf("%d ", ptr[j]);
        }
        printf("\n");

        // Free allocated memory
        free(ptr);
    }

    return 0;
}

In this example, we dynamically allocate memory based on the size entered by the user. After allocation, we assign values to each element of the array and then display them.

For example, if the user enters 5, the program allocates memory for 5 integers and stores the values 1, 2, 3, 4, 5.

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

Dynamic Array Using calloc() Function

The "calloc" method, commonly known as the "contiguous allocation" method in C, dynamically allocates the requested number of memory blocks of the specified type and initializes each block with a default block of 0.

The process of creating a dynamic array is similar to the malloc() function. The difference is that calloc() takes two arguments instead of one as compared to malloc(). So in the calloc() function we provide the size of each element and the number of elements required in the dynamic array. Also, each element in the array is initialized to zero.

Following is the syntax of calloc() function

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

In the syntax below, we have created a dynamic array of type float with six elements.

ptr = (int*) calloc(6, sizeof(float));

Example: Creating a Dynamic Array using calloc Function

Let’s see a C program to create a dynamic array using the "calloc()" function −

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

int main() {
   int* ptr;
   int len;

   // Size of the array
   printf("Enter size of elements:");
   scanf("%d", &len);

   // use calloc
   ptr = (int*)calloc(len, sizeof(int));

   if (ptr == NULL) {
       printf("Memory not allocated.\n");
   }
   else {
      printf("Memory successfully allocated using "
               "calloc.\n");

      for (int i = 0; i < len; ++i) {
         ptr[i] = i + 1;
      }

      printf("The elements of the array are: ");
      for (int j = 0; j < len; ++j) {
         printf("%d, ", ptr[j]);
      }
   }
   return 0;
}

In the above example, we dynamically allocate memory using the calloc() function based on the size entered by the user. Unlike malloc(), calloc() initializes all the allocated memory blocks to zero before assigning values. After allocation, we store values in each element of the array and then display them.

If the user enters 7, the program allocates memory for 7 integers and stores the values 1, 2, 3, 4, 5, 6, 7.

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

Dynamic Resizing of an Array Using realloc() Function

The realloc() function, or re-allocation, is used to dynamically change the memory size of a previously allocated block.

Following is the syntax of realloc() function

ptr = realloc(ptr, newSize);

Example: Resizing an Array using realloc Function

Let's create a C program example to understand the realloc() function and how we can resize a dynamic array using it −

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

int main() {
   int* ptr;
   int len = 5;

   //  Memory allocates dynamically using calloc()
   ptr = (int*)calloc(len, sizeof(int));

   if (ptr == NULL) {
      printf("Memory not allocated.\n");
      exit(0);
   }
   else {
      printf("Memory successfully allocated using "
              "calloc.\n");
   }

   for (int i = 0; i < len; ++i) {
      ptr[i] = i + 1;
   }

   printf("The elements of the array are: ");
   for (int j = 0; j < len; ++j) {
      printf("%d, ", ptr[j]);
   }

   printf("\n");

   len = 10;

   int *temp = ptr;

   //  using realloc
   ptr = realloc(ptr, len * sizeof(int));
   if (!ptr) {
      printf("Memory Re-allocation failed.");
      ptr = temp;
   }
   else {
      printf("Memory successfully re-allocated using realloc.\n");
   }

   // inserting new elements
   for (int i = 5; i < len; ++i) {
      ptr[i] = i + 10;
   }

   printf("The new elements of the array are: ");
   for (int j = 0; j < len; ++j) {
      printf("%d, ", ptr[j]);
   }
   return 0;
}

In this program, memory is first allocated dynamically for 5 integers using calloc(), where the values 1 to 5 are stored and displayed. After that, the memory block is expanded to hold 10 integers using realloc(), and new values are assigned to the additional elements. Finally, the complete array with both the old and new values is printed.

Memory successfully allocated using calloc.
The elements of the array are: 1, 2, 3, 4, 5, 
Memory successfully re-allocated using realloc.
The new elements of the array are: 1, 2, 3, 4, 5, 15, 16, 17, 18, 19,

Difference: malloc(), calloc(), and realloc()

The following table compares and contrasts the features of these three functions: malloc, calloc, and realloc −

Function Purpose Initialization Syntax Return Value
malloc() Allocates a single block of memory of given size. If memory is not initialize (contains garbage value) ptr = (int*)malloc(n * sizeof(int)); Returns a pointer to the allocated block, or NULL if allocation fails.
calloc() Allocates multiple blocks and initialize them All allocated bytes are set to zero ptr = (int*)calloc(n, sizeof(int)); Returns a pointer to the allocated block, or NULL if allocation fails.
realloc() Resized the size of already allocated block When you increase the size of memory, existing value are remains unchanged. And the newly allocated part is not initialized so it contains garbage value. ptr = (int*)realloc(ptr, new_size); Returns a pointer to the allocated block, or NULL if reallocation fails.

Conclusion

Dynamic arrays in C provide flexibility by allowing memory to be allocated and resized at runtime using functions like malloc(), calloc(), and realloc(). Unlike static arrays, they help optimize memory usage and handle scenarios where the required size is not known in advance.

Advertisements