C realloc() Function | Resize Dynamically Allocated Memory

Introduction

The realloc() function in C is a standard library function that changes the size of a previously allocated memory block. It is part of the C standard library (stdlib.h). This function is useful for resizing dynamic memory allocations without losing the existing data.

It allows you to expand or shrink the size of the memory block dynamically while preserving the existing data up to the minimum of the old and new sizes.

realloc() Function Syntax

The syntax for the realloc() function is as follows:

void *realloc(void *ptr, size_t size);

Parameters:

  • ptr: A pointer to the memory block previously allocated with malloc(), calloc(), or realloc(). If ptr is NULL, realloc() behaves like malloc().
  • size: The new size of the memory block in bytes.

Returns:

  • The function returns a pointer to the newly allocated memory block. If the reallocation fails, it returns NULL, and the original block remains unchanged.

Understanding realloc() Function

The realloc() function attempts to resize the memory block pointed to by ptr to size bytes. If the new size is larger, the additional memory is not initialized. If realloc() fails to allocate the requested memory, it returns NULL, and the original memory block remains unchanged. It is important to assign the return value to a new pointer variable to avoid losing the reference to the original memory block in case of failure.

Examples

Resizing an Array

To demonstrate how to use realloc() to resize an array, we will write a simple program.

Example

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

int main() {
    int *array;
    int initial_size = 5;
    int new_size = 10;
    int i;

    // Allocate initial memory for an array of integers
    array = (int *)malloc(initial_size * sizeof(int));
    if (array == NULL) {
        printf("Initial memory allocation failed.\n");
        return 1;
    }

    // Initialize the initial array
    for (i = 0; i < initial_size; i++) {
        array[i] = i * 2;
    }

    // Resize the array
    int *new_array = (int *)realloc(array, new_size * sizeof(int));
    if (new_array == NULL) {
        printf("Memory reallocation failed.\n");
        free(array);
        return 1;
    }
    array = new_array;

    // Initialize the new elements
    for (i = initial_size; i < new_size; i++) {
        array[i] = i * 2;
    }

    // Print the resized array
    for (i = 0; i < new_size; i++) {
        printf("array[%d] = %d\n", i, array[i]);
    }

    // Free the allocated memory
    free(array);

    return 0;
}

Output:

array[0] = 0
array[1] = 2
array[2] = 4
array[3] = 6
array[4] = 8
array[5] = 10
array[6] = 12
array[7] = 14
array[8] = 16
array[9] = 18

Handling Reallocation Failure

This example shows how to handle reallocation failure using realloc().

Example

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

int main() {
    int *array;
    int initial_size = 5;
    int new_size = 1000000000;  // Intentionally large size to trigger failure

    // Allocate initial memory for an array of integers
    array = (int *)malloc(initial_size * sizeof(int));
    if (array == NULL) {
        printf("Initial memory allocation failed.\n");
        return 1;
    }

    // Resize the array
    int *new_array = (int *)realloc(array, new_size * sizeof(int));
    if (new_array == NULL) {
        printf("Memory reallocation failed.\n");
        free(array);
        return 1;
    }
    array = new_array;

    // Free the allocated memory
    free(array);

    return 0;
}

Output:

Memory reallocation failed.

Real-World Use Case

Dynamic Buffer Management

In real-world applications, dynamic buffer management often requires resizing buffers as data grows. The realloc() function can be used to efficiently manage buffer sizes.

Example: Dynamic String Buffer

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

int main() {
    char *buffer;
    size_t buffer_size = 16;
    size_t len = 0;

    // Allocate initial memory for the buffer
    buffer = (char *)malloc(buffer_size * sizeof(char));
    if (buffer == NULL) {
        printf("Initial memory allocation failed.\n");
        return 1;
    }

    // Simulate reading data into the buffer and resizing if necessary
    const char *data = "This is a long string that will exceed the initial buffer size.";
    size_t data_len = strlen(data);

    // Check if resizing is needed
    if (data_len >= buffer_size) {
        size_t new_size = buffer_size * 2;
        char *new_buffer = (char *)realloc(buffer, new_size * sizeof(char));
        if (new_buffer == NULL) {
            printf("Memory reallocation failed.\n");
            free(buffer);
            return 1;
        }
        buffer = new_buffer;
        buffer_size = new_size;
    }

    // Copy the data into the buffer
    strcpy(buffer, data);

    // Print the buffer contents
    printf("Buffer contents: %s\n", buffer);

    // Free the allocated memory
    free(buffer);

    return 0;
}

Output:

Buffer contents: This is a long string that will exceed the initial buffer size.

Conclusion

The realloc() function is used for dynamic memory management in C. It allows for resizing previously allocated memory blocks, providing flexibility in handling varying memory requirements at runtime. Always ensure to check for successful reallocation and handle potential failures to maintain robust applications.

Comments