Dynamic Array Resizing in C



Dynamic arrays are arrays whose size can change during runtime. To manage dynamic arrays in C, memory is allocated at runtime using pointers and functions from the <stdlib.h> header file. Specifically, malloc() and calloc() are the two primary functions used to allocate memory for dynamic arrays.

  • malloc() (memory allocation) allocates a specified number of bytes of memory but does not initialize them.
  • calloc() (contiguous allocation) allocates memory for an array of elements and initializes all the bytes to zero.

In this chapter, we will see how we can resize this allocated memory for dynamic arrays.

Dynamic Array Resizing

We can resize dynamic arrays by increasing or decreasing the dynamically allocated memory using the realloc() function. If more elements need to be stored, we can increase the size or if fewer elements are required, we can decrease it.

We will look at how to resize memory using the realloc() function, and then how to free the allocated memory in C using −

We will also look at −

Next, we will go through each function in detail and see how it allocates and frees memory with examples.

Dynamic Memory Using realloc() Function

The realloc() funciton in C is used to resize a previously allocated memory block. It can increase or decrease the size of a dynamic array while preserving the existing data.

Following is the syntax for reallocating memory using the realloc() function in C −

ptr = (castType*) realloc(pointer, new_size_in_bytes);

Here, ptr is the pointer to the previously allocated memory, castType is the type of the pointer (like int* or float*), and new_size_in_bytes is the new size of the memory block.

Example of realloc() Function

In this example, we first allocate memory for an array of three integers using malloc() funciton. Then, we resize the array to five integers using realloc() function, assign values, and print the array elements.

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

int main() {
    int *numbersArray;
    int index;

    // Allocate memory for 3 integers
    numbersArray = (int*) malloc(3 * sizeof(int));

    // Check if memory allocation was successful
    if(numbersArray == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    } else {
        printf("Memory successfully allocated for 3 elements.\n");
    }

    // Assign values to the array
    for(index = 0; index < 3; index++) {
        numbersArray[index] = (index + 1) * 10;  // Store 10, 20, 30
    }

    // Resize memory to hold 5 integers
    numbersArray = (int*) realloc(numbersArray, 5 * sizeof(int));

    // Check if memory reallocation was successful
    if(numbersArray == NULL) {
        printf("Memory reallocation failed\n");
        return 1;
    } else {
        printf("Memory successfully reallocated for 5 elements.\n");
    }

    // Assign values to the new elements
    for(index = 3; index < 5; index++) {
        numbersArray[index] = (index + 1) * 10;  // Store 40, 50
    }

    // Print all values
    printf("Array elements after realloc: ");
    for(index = 0; index < 5; index++) {
        printf("%d ", numbersArray[index]);
    }
    return 0;
}

Following is the output of the above program where we reallocate the previously allocated array and display its elements.

Memory successfully allocated for 3 elements.
Memory successfully reallocated for 5 elements.
Array elements after realloc: 10 20 30 40 50 

free() Function

The free() function in C is used to deallocate/release memory that was previously allocated dynamically using malloc(), calloc(), or realloc(). This gives the memory back to the system and helps prevent memory leaks. After freeing, the pointer still exists, but the memory it points to is no longer valid, so don't use the pointer after freeing it.

The syntax for using free() function is −

free(pointer);

Here, pointer is the pointer to the memory block we want to deallocate.

Example of free() Function

In this example, we use malloc() fucntion to allocate memory for an array of five integers. We store values in the array, display them, and then free the allocated memory using the free() funciton.

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

int main() {
    int *numbersArray;  // Pointer for dynamic array
    int index;

    // Allocate memory for 5 integers
    numbersArray = (int*) malloc(5 * sizeof(int));

    // Check if memory allocation was successful
    if(numbersArray == NULL) {
        printf("Memory allocation failed\n");
        return 1;
    } else {
        printf("Memory successfully allocated for the array.\n");
    }

    // Assign values to the array
    for(index = 0; index < 5; index++) {
        numbersArray[index] = (index + 1) * 10;  // Store 10, 20, 30, 40, 50
    }

    // Print the values
    printf("Array elements: ");
    for(index = 0; index < 5; index++) {
        printf("%d ", numbersArray[index]);
    }
    printf("\n");

    // Free the allocated memory
    free(numbersArray);
    printf("Memory has been freed.\n");
    return 0;
}

Following is the output of the program showing the array allocation, its elements, and successful memory deallocation.

Memory successfully allocated for the array.
Array elements: 10 20 30 40 50 
Memory has been freed.

Variable-Length Arrays (VLAs)

Variable-Length Arrays (VLAs) in C are arrays whose size is decided at runtime. Unlike dynamic arrays that are created on the heap using functions like malloc(), variable-length arrays are created on the stack, which means they are automatically freed when the function ends.

Variable-Length Arrays are supported only in C99 and later standards, and their size must always be a positive value. It cannot be zero.

Following is the syntax for declaring a variable length array in C −

data_type arrayName[size];

Here, data_type is the type of elements (like int or float), arrayName is the name of the array, and size is a value that is decided at runtime.

Example of Variable-Length Array

In this example, we decide the array size at runtime using a variable. The VLA numbers[size] is created on the stack. We store values in a loop and print them. The memory is automatically freed when the program ends.

#include <stdio.h>

int main() {
    int size = 5;  // Size decided at runtime
    int index;

    // Create a Variable-Length Array
    int numbers[size];

    // Store values in the array
    for(index = 0; index < size; index++) {
        numbers[index] = (index + 1) * 10;  // Store 10, 20, 30, 40, 50
    }

    // Print the array
    printf("Array elements: ");
    for(index = 0; index < size; index++) {
        printf("%d ", numbers[index]);
    }
    return 0;
}

Following is the output of the above program that displays the elements of the variable length array.

Array elements: 10 20 30 40 50

Array Members in Structures

Arrays can be members of structures in C. They can have a fixed size, which is allocated along with the structure, or be pointer-based, which requires dynamic memory allocation using malloc() or calloc() functions.

Following is the syntax for a fixed-size array inside a structure in C −

struct StructName {
    data_type arrayName[size];
    // other members
};

Here, data_type is the type of elements, arrayName is the name of the array, and size is determined at compile time.

Following is the syntax for a pointer-based dynamic array inside a structure in C −

struct StructName {
    data_type *arrayName;
    int size;  // store the array size
    // other members
};

Here, data_type *arrayName is a pointer to the array elements, and size stores the number of elements.

Some important points to know −

  • Fixed-size arrays inside structures have memory allocated along with the structure.
  • Pointer-based arrays require dynamic memory allocation using malloc() or calloc() functions.
  • Always free dynamically allocated memory after use to prevent memory leaks.

Example of Array as Structure Member

In this example, we create a structure Student with a pointer to an array of marks. Memory is dynamically allocated for 3 subjects. Then, we store the values in the array and print them. Finally, we free the allocated memory.

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

struct Student {
    int *marks;  // Pointer for dynamic array
    int subjects;
};

int main() {
    struct Student s1;
    int i;
    s1.subjects = 3;

    // Allocate memory for marks
    s1.marks = (int*) malloc(s1.subjects * sizeof(int));

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

    // Store values in the array
    for(i = 0; i < s1.subjects; i++) {
        s1.marks[i] = (i + 1) * 10;  // 10, 20, 30
    }

    // Print the marks
    printf("Marks of student: ");
    for(i = 0; i < s1.subjects; i++) {
        printf("%d ", s1.marks[i]);
    }
    // Free allocated memory
    free(s1.marks);
    return 0;
}

Following is the output that displays the marks of the student −

Marks of student: 10 20 30

In this chapter, we learned how to resize arrays in C using realloc() function and free memory using free() function. We also covered variable-length arrays, arrays in structures, and overall memory management in C. We can also create a two-dimensional dynamic array in C, and there are different functions for this.

Advertisements