Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Dynamic Memory Allocation
2.1.
1. C malloc() method
2.1.1.
Syntax 
2.1.2.
Example
2.2.
2. C calloc() method
2.2.1.
Syntax 
2.2.2.
Example
2.3.
3. C free() method
2.3.1.
Syntax 
2.3.2.
Example
2.4.
4. C realloc() method
2.4.1.
Syntax
2.4.2.
Example
2.5.
5. Using Variable Length Arrays(VLAs)
2.5.1.
Syntax
2.5.2.
Example
2.6.
6. Using Flexible Array Members
2.6.1.
Syntax
2.6.2.
Example
3.
Dynamically Allocate a 2D array.
3.1.
1. Using Single Pointer
3.1.1.
Example
3.2.
2. Using Array of Pointers
3.2.1.
Example
3.3.
3. Using Double Pointer
3.3.1.
Example
3.4.
4. Using Pointer to a Pointer 
3.4.1.
Example 
3.5.
5. Using a Pointer to Variable Length Array
3.5.1.
Example
4.
Advantages of Dynamic Arrays
5.
Disadvantages of Dynamic Arrays
6.
Frequently Asked Questions
6.1.
Can I create dynamic array in C?
6.2.
When to use dynamic arrays in C?
6.3.
What are the properties of dynamic arrays in C?
6.4.
How to dynamically allocate array size in C?
7.
Conclusion
Last Updated: Mar 27, 2024
Medium

Dynamic arrays in C

Introduction

We'll learn how to use standard library functions like malloc() and calloc() to create a dynamic Array in c in this blog.

An array is a collection of a fixed number of values. You can't change the size of an array once it's been declared.

It's possible that the size of the Array you declared is insufficient at times. You can manually set RAM during runtime to remedy this problem. In C programming, we called it dynamic memory allocation. Malloc(), calloc(), and realloc() are library functions that are used to allocate memory dynamically. 

dynamic array in c

The header file <stdlib.h> defines these functions.

Also see: C Static Function and  Short int in C Programming

Dynamic Memory Allocation

C Dynamic Memory Allocation is a process for changing the size of a Data Structure (such as an Array) during runtime.

  • C malloc() method
     
  • C calloc() method
     
  • C free() method
     
  • C realloc() method
     
  • Using Variable Length Arrays(VLAs)
     
  • Using Flexible Array Members

1. C malloc() method

In C, the "malloc" or "memory allocation" method is used to allocate a single huge block of memory with the specified size dynamically. It returns a void pointer that can be cast into any other type of pointer. Because it does not initialize memory at runtime, each block is initially set to the default garbage value.

Syntax 

ptr = (cast-type*) malloc(byte-size)
For Example:
ptr = (int*) malloc(100 * sizeof(int));


This statement will allocate 400 bytes of RAM because int is 4 bytes long. Pointer ptr holds the address of the allocated memory's first byte.

If space is insufficient, allocation fails and returns a NULL pointer.

Example

#include <stdio.h>
#include <stdlib.h>
int main() {
    int* ptr;
    int n, i;
    printf("Enter number of elements:");
    scanf("%d",&n);
    printf("Entered number of elements: %d\n", n);
    ptr = (int*)malloc(n * sizeof(int));
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    }
    else {
        printf("Memory successfully allocated using malloc.\n");
        for (i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }
        printf("The elements of the array are: ");
        for (i = 0; i < n; ++i) {
            printf("%d, ", ptr[i]);
        }
    }
    return 0;
}


Output 

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

2. C calloc() method

In C, the "calloc" or "contiguous allocation" method is used to allocate a specified number of blocks of memory of the specified type dynamically. It's fairly similar to malloc(), but it has two key differences:

It sets the default value for every block to 0.

In comparison to malloc(), it has two parameters or arguments.

Syntax 

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


here, n is the num of elements and element-size is the size of each element.

For Example: 

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


This statement allocates contiguous space in memory for 25 elements, each with the size of the float.

If space is insufficient, allocation fails, and it returns a NULL pointer.

Example

#include <stdio.h>
#include <stdlib.h> 
int main() {
    int* ptr;
    int n, i;
    n = 5;
    printf("Enter total number of elements present in an array: %d\n", n);
    ptr = (int*)calloc(n, sizeof(int));
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    }
    else {
        printf("Memory successfully allocated.\n");
        for (i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }
        printf("The elements in an array are: ");
        for (i = 0; i < n; ++i) {
            printf("%d, ", ptr[i]);
        }
    }
 
    return 0;
}


Output

Enter the total number of elements present in an array: 5
Memory successfully allocated.
The elements in an Array are: 1, 2, 3, 4, 5,

3. C free() method

To dynamically de-allocate memory in C, use the "free" technique. Memory allocated with the malloc() and calloc() procedures is not de-allocated on their own. As a result, anytime dynamic memory allocation occurs, the free() function is employed. It frees up memory, which helps to prevent memory waste.

Syntax 

free(ptr);


Example

C example

#include <stdio.h>
#include <stdlib.h>
int main() {
    int *ptr, *ptr1;
    int n, i;
    n = 5;
    printf("Enter the total number of elements: %d\n", n);
    ptr = (int*)malloc(n * sizeof(int));
    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;
}


Output

Enter the total number of elements: 5
Memory successfully allocated using malloc.
Malloc Memory successfully freed.

Memory successfully allocated using calloc.
Calloc memory successfully freed.

4. C realloc() method

In C, the "realloc" or "re-allocation" method is used to alter the memory allocation of a previously allocated memory dynamically. In other words, realloc can be used to dynamically re-allocate memory if the memory originally allocated with malloc or calloc is inadequate. The existing value is preserved after re-allocation of memory, and new blocks are initialized with the default garbage value.

Syntax

ptr = realloc(ptr, newSize);


Where ptr is re-allocated-allocated with new size 'newSize.'

If space is insufficient, then allocation fails and returns a NULL pointer.

Example

C example

#include <stdio.h>
#include <stdlib.h> 
int main() {
    int* ptr;
    int n, i;
    n = 5;
    printf("Enter the total number of elements: %d\n", n);
    ptr = (int*)calloc(n, sizeof(int));
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    }
    else {
        printf("Memory successfully allocated using calloc.\n");
        for (i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }
        printf("Elements are: ");
        for (i = 0; i < n; ++i) {
            printf("%d, ", ptr[i]);
        }
        n = 10;
        printf("\n\nEnter the new size of an array: %d\n", n);
        ptr = realloc(ptr, n * sizeof(int)); 
       
        printf("Memory successfully re-allocated using realloc.\n");
 
        for (i = 5; i < n; ++i) {
            ptr[i] = i + 1;
        }
        printf("Elements are:");
        for (i = 0; i < n; ++i) {
            printf("%d, ", ptr[i]);
        }
        free(ptr);
    }
    return 0;
}


Output

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

Enter the new size of an array: 10
Memory successfully re-allocatedre-allocated using realloc.
Elements are: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,

 

Must Read Passing Arrays to Function in C

5. Using Variable Length Arrays(VLAs)

Variable length arrays also allow us to create an array whose size can be changed at runtime. It helps to create variable length arrays in C programming language from the C99 version upwards.

Syntax

datatype arrayname[size];

Example

#include <stdio.h>
int main() {
   int size;
   printf("Enter the size of the array: ");
   scanf("%d", &size);
   int array[size];  // Variable Length Array
   printf("Enter %d elements:\n", size);
   for (int i = 0; i < size; i++) {
       scanf("%d", &array[i]); // taking input of variable length array
   }
   printf("The elements of the Variable Length Array are:\n");
   for (int i = 0; i < size; i++) {
       printf("%d ", array[i]);
   }
   printf("\n");
   return 0;
}


Output

Enter the size of the array: 3
Enter 3 elements:
5 8 12
The elements of the Variable Length Array are:
5 8 12

6. Using Flexible Array Members

Flexible array members (FAM) allow us to create an array whose size is flexible in C programming language from the C99 version upwards. The FAM is declared inside a structure along with its size, which can be changed at runtime.

Syntax

struct MyStruct {
   // Other members
   dataType data[]; // Flexible Array Member
};


The memory allocation of the flexible array members can be done by malloc.

struct MyStruct* myStruct = malloc(sizeof(struct MyStruct) + arraySize * sizeof(elementType));

Example

Let us look at an example of using flexible array members.

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

struct MyStruct {
    int length;
    int data[];  // Flexible Array Member
};

int main() {
    int size;
    printf("Enter the size of the array: ");
    scanf("%d", &size);

    struct MyStruct* myStruct = malloc(sizeof(struct MyStruct) + size * sizeof(int));  // Memory Allocation of Flexible Array Member
    myStruct->length = size;

    printf("Enter %d elements:\n", size);
    for (int i = 0; i < size; i++) {
        scanf("%d", &myStruct->data[i]);  // Taking input of the Flexible Array Member
    }

    printf("The elements of the flexible array member are:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", myStruct->data[i]);
    }
    printf("\n");

    free(myStruct);
    return 0;
}


Output

Enter the size of the array: 5
Enter 5 elements:
10 20 30 40 50
The elements of the flexible array member are:
10 20 30 40 50

Dynamically Allocate a 2D array.

1. Using Single Pointer

We allocate memory of size M N dynamically and assign it to the pointer in this approach. Even though the memory is allocated linearly, we can index the 2D Array using pointer arithmetic.

Example

#include <stdio.h>
#include <stdlib.h>
 
// `M × N` matrix
#define M 4
#define N 5
 
// Here Dynamically allocate memory for 2D Array
int main() {
    int* X= (int*)malloc(M * N * sizeof(int));
 
    if (X == NULL) {
        fprintf(stderr, "Out of memory");
        exit(0);
    }
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            *(X + r*N + c) = rand() % 100;            
        }
    }
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            printf("%d ", (X + r*N)[c]); // or, use *(X + r*N + c)
        }
        printf("\n");
    }
 
    // deallocate memory
    free(X);
    return 0;
}


Output

83 86 77 15 93 
35 86 92 49 21 
62 27 90 59 63 
26 40 26 72 36 

2. Using Array of Pointers

As seen below, we can dynamically generate an array of size M pointers and then dynamically allocate memory of size N for each row:

Example

#include <stdio.h>
#include <stdlib.h>
 
// `M × N` matrix
#define M 4
#define N 5
 
int main() {
    int *X[M];
    if (X == NULL) {
        fprintf(stderr, "Out of memory");
        exit(0);
    }
 
    for (int r = 0; r < M; r++) {
        X[r] = (int *)malloc(N * sizeof(int));
        if (X[r] == NULL) {
            fprintf(stderr, "Out of memory");
            exit(0);
        }
    }
 
    // assign values to the allocated memory
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            X[r][c] = rand() % 100; // or *(X[r] + c) or *(*(X + r) + c)
        }
    }
    // print the 2D array
    for (int r = 0; r < M; r++)
    {
        for (int c = 0; c < N; c++) {
            printf("%d ", X[r][c]); // or *(X[r] + c) or *(*(X + r) + c)
        }
        printf("\n");
    } 
    // deallocate memory
    for (int r = 0; r < M; r++) {
        free(X[r]);
    }
    // free(X);
    return 0;
}


Output

83 86 77 15 93 
35 86 92 49 21 
62 27 90 59 63 
26 40 26 72 36 

Check out Longest Common Substring

3. Using Double Pointer

As seen in the second technique, we begin by generating an array of pointers of size M. Then allocate memory of size M N dynamically and let *A point to it. Finally, spread the memory that has been allocated over M pointers.

Example

#include <stdio.h>
#include <stdlib.h>
 
// `M × N` matrix
#define M 4
#define N 5
int main() {
    int **X = (int **)malloc(M * sizeof(int *)); // or, use `int* X[M]`
    if (X == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(0);
    }
    // dynamically allocate memory of size `M × N` and let *X point to it
    *X = (int *)malloc(sizeof(int) * M * N);
 
    // position allocated memory across `M` pointers
    for (int r = 0; r < M; r++) {
        X[r] = (*X + N*r);
    }
 
    // assign values to the allocated memory
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            X[r][c] = rand() % 100; // or *(X[r] + c) or *(*(X + r) + c)            
        }
    }
    // print the 2D array
    for (int r = 0; r < M; r++) {
        for (int c = 0; c < N; c++) {
            printf("%d ", X[r][c]); // or *(X[r] + c) or *(*(X + r) + c)
        }
        printf("\n");
    }
    // deallocate memory
    free(*X);
    free(X);
    return 0;
}


Output

83 86 77 15 93 
35 86 92 49 21 
62 27 90 59 63 
26 40 26 72 36 

4. Using Pointer to a Pointer 

A double-pointer can also be used to dynamically build an array of pointers. Once we have an array of pointers allocated dynamically, we can dynamically allocate memory for every row like method 2. 

Example 

#include <stdio.h>
#include <stdlib.h>
 
int main() {
    int r = 2, c = 4, i, j, count;
 
    int** arr = (int**)malloc(r * sizeof(int*));
    for (i = 0; i < r; i++)
        arr[i] = (int*)malloc(c * sizeof(int));
 
    // Note that arr[i][j] is same as *(*(arr+i)+j)
    count = 0;
    for (i = 0; i < r; i++)
        for (j = 0; j < c; j++)
            arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count
 
    for (i = 0; i < r; i++)
        for (j = 0; j < c; j++)
            printf("%d ", arr[i][j]);
 
    /* Code for further processing and free the
       dynamically allocated memory */
 
    for (int i = 0; i < r; i++)
        free(arr[i]);
    free(arr);
    return 0;
}


Output 

1 2 3 4 5 6 7 8

5. Using a Pointer to Variable Length Array

The kind of variable determines the dimensions of VLA. As a result, one can create a pointer to an array with a shape that is defined at runtime.

The pointer has to be dereferenced before subscribing with syntax (*arr)[i][j].

Example

#include <stdio.h>
#include <stdlib.h>
int main() {
    int row = 2, col = 4, i, j, count;
    int (*arr)[row][col] = malloc(sizeof *arr);   
    count = 0;
    for (i = 0; i < row; i++)
        for (j = 0; j < col; j++)
            (*arr)[i][j] = ++count;
 
    for (i = 0; i < row; i++)
        for (j = 0; j < col; j++)
            printf("%d ", (*arr)[i][j]);
 
    free(arr);    
    return 0;
}


Output

1 2 3 4 5 6 7 8

Advantages of Dynamic Arrays

Here are some of the advantages of using dynamic arrays in C.

  • Dynamic arrays do not have fixed size so we can increase the size of dynamic arrays whenever we want.
     
  • To get the element at any position in dynamic arrays takes O(1) time which is pretty efficient in comparison to linked lists and hashtables.
     
  • Dynamic arrays are easy to manage. We can access any element as we do in the case of static arrays.
     
  • We can delete the last element that is added to the dynamic array in O(1) time, which is very helpful in some cases.

Disadvantages of Dynamic Arrays

Let us look at some of the disadvantages of dynamic arrays before using them.

  • Element insertion in a dynamic array takes linear time, while element insertion in cases of sets and maps is O(log n) time.
     
  • When the size of dynamic arrays gets filled, it might take some time to resize because the whole array is shifted to a new position. 
     
  • We cannot store different types of elements in dynamic arrays as we do in the case of a list.
     
  • It might access more memory in some cases when the size of the array is filled as all the elements are shifted to a new location to adjust more elements in the array.


Also see,   Tribonacci Series

what is storage class in c 

 Decision Making in C

Frequently Asked Questions

Can I create dynamic array in C?

Yes, it is possible to create a dynamic array in C using pointers and memory allocation functions such as malloc(), calloc(), or realloc(). These functions allow programmers to allocate and deallocate memory dynamically at runtime, enabling the creation of arrays of varying sizes.

When to use dynamic arrays in C?

Dynamic arrays in C are useful when the size of the array is not known at compile time and needs to be determined at runtime. They are useful when the array size may need to be changed during program execution.

What are the properties of dynamic arrays in C?

Dynamic arrays in C have the following properties: They can be resized during program execution using memory allocation functions, they are allocated on the heap rather than the stack, they can be used to store any type of data.

How to dynamically allocate array size in C?

In C, dynamic array size allocation can be done using memory allocation functions such as malloc(), calloc(), or realloc(). These functions allocate memory on the heap at runtime and return a pointer to the allocated memory block, which can be used as an array of the desired size.

Conclusion

In this article, we have extensively discussed dynamic array in c, Dynamic Memory Allocation using malloc() calloc().

Must Read: Array in Javascript

We hope that this blog enhances your knowledge regarding Dynamic arrays, Dynamic Memory Allocation using malloc(), calloc(),  and if you would like to learn more about arrays, you can also try solving the Sum Of Two Arrays problem. Do upvote our blog to help other ninjas grow. 

Happy Coding!

Live masterclass