DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C MemoryTopic 60 of 64
←PreviousPrevNextNext→

C Reallocate Memory

Introduction to Memory Reallocation

Memory reallocation is the process of resizing previously allocated memory blocks. The realloc() function allows you to adjust the size of dynamically allocated memory, making it larger or smaller as needed during program execution.

Key use cases for reallocation:

- Dynamic arrays that need to grow or shrink

- Buffers that need to accommodate variable-sized data

- Memory optimization by reducing oversized allocations

- Efficient memory usage in data structures

realloc() Function Syntax

Parameters:

- ptr: Pointer to previously allocated memory (can be NULL)

- new_size: New size in bytes for the memory block

Return value:

- Pointer to resized memory block, or NULL if reallocation fails

- On failure (NULL), the original memory block remains allocated and unchanged

Example
void* realloc(void* ptr, size_t new_size);
ℹ️ Note: If ptr is NULL, realloc() behaves like malloc(new_size). If new_size is 0 and ptr is not NULL, the block is freed; the function may return NULL or a unique pointer value—do not use it. Prefer calling free(ptr) and setting ptr = NULL when you want to release memory.

Basic realloc() Usage

⚠️ Warning: Always assign realloc() to a temporary pointer to avoid losing the original block on failure. Initialize any newly added region after a successful growth.
Example
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *arr = malloc(3 * sizeof *arr);
    if (arr == NULL) {
        printf("Initial allocation failed!\n");
        return 1;
    }
    for (int i = 0; i < 3; i++) arr[i] = (i + 1) * 10;

    printf("Original array: ");
    for (int i = 0; i < 3; i++) printf("%d ", arr[i]);

    int *tmp = realloc(arr, 6 * sizeof *arr); // use a temporary pointer
    if (tmp == NULL) {
        printf("\nReallocation failed! Keeping original size.\n");
        free(arr);
        return 1;
    }
    arr = tmp; // only assign on success

    // Newly obtained elements have indeterminate values—initialize them
    for (int i = 3; i < 6; i++) arr[i] = (i + 1) * 10;

    printf("\nResized array: ");
    for (int i = 0; i < 6; i++) printf("%d ", arr[i]);
    printf("\n");

    free(arr);
    return 0;
}
Output
Original array: 10 20 30 
Resized array: 10 20 30 40 50 60

Safe realloc() Pattern

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

int main(void) {
    int *arr = malloc(2 * sizeof *arr);
    if (arr == NULL) return 1;
    arr[0] = 100; arr[1] = 200;

    int *temp = realloc(arr, 4 * sizeof *arr);
    if (temp == NULL) {
        printf("Reallocation failed! Original array preserved: %d %d\n", arr[0], arr[1]);
        free(arr);
        return 1;
    }
    arr = temp;
    arr[2] = 300; arr[3] = 400;

    printf("Resized successfully: ");
    for (int i = 0; i < 4; i++) printf("%d ", arr[i]);
    printf("\n");

    free(arr);
    return 0;
}
Output
Resized successfully: 100 200 300 400
ℹ️ Note: This pattern ensures you never lose access to the original memory if reallocation fails.

Overflow-Safe Growth (Capacity Doubling)

When computing sizes (count * sizeof(T)), guard against integer overflow before calling realloc(). Use size_t and check against SIZE_MAX.

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

int grow_int_array(int **p, size_t *cap) {
    size_t new_cap = (*cap == 0) ? 1 : (*cap * 2);
    if (new_cap > SIZE_MAX / sizeof **p) {
        return 0; // overflow
    }
    int *tmp = realloc(*p, new_cap * sizeof **p);
    if (!tmp) return 0;
    *p = tmp;
    *cap = new_cap;
    return 1;
}

int main(void) {
    int *a = NULL; size_t cap = 0;
    if (!grow_int_array(&a, &cap)) { puts("grow failed"); return 1; }
    printf("Capacity now %zu\n", cap);
    free(a);
    return 0;
}

realloc() with NULL Pointer

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

int main(void) {
    int *arr = NULL;                // no allocation yet
    arr = realloc(arr, 3 * sizeof *arr); // behaves like malloc
    if (arr == NULL) {
        printf("Allocation failed!\n");
        return 1;
    }
    for (int i = 0; i < 3; i++) arr[i] = i * 5;

    printf("Array created with realloc(NULL): ");
    for (int i = 0; i < 3; i++) printf("%d ", arr[i]);
    printf("\n");

    free(arr);
    return 0;
}
Output
Array created with realloc(NULL): 0 5 10

Shrinking Memory with realloc()

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

int main(void) {
    int *arr = malloc(6 * sizeof *arr);
    if (arr == NULL) return 1;
    for (int i = 0; i < 6; i++) arr[i] = (i + 1) * 10;

    printf("Original (6 elements): ");
    for (int i = 0; i < 6; i++) printf("%d ", arr[i]);

    int *temp = realloc(arr, 3 * sizeof *arr);
    if (temp == NULL) {
        printf("\nShrinking failed!\n");
        free(arr);
        return 1;
    }
    arr = temp;

    printf("\nAfter shrinking (3 elements): ");
    for (int i = 0; i < 3; i++) printf("%d ", arr[i]);
    printf("\n");

    free(arr);
    return 0;
}
Output
Original (6 elements): 10 20 30 40 50 60 
After shrinking (3 elements): 10 20 30
ℹ️ Note: After shrinking, any previous pointers/indexes to elements beyond the new size are invalid.

realloc() Implementation Details

realloc() may work in different ways:

- In-place expansion: If there is free space after the current block, it may extend it without moving.

- Move + copy: If no space is available, it allocates a new block, copies the old data, and frees the old block.

- Bookkeeping change: On shrink, it may simply adjust internal metadata.

Regardless, you must assume the original pointer becomes invalid after a successful realloc() call (unless you kept it in a temp and compare), and any other pointers into the old block are indeterminate.

Common realloc() Pitfalls

  • Assigning realloc() directly to the original pointer (risk of leak on failure).
  • Using pointers into the old block after a successful reallocation (they may be dangling).
  • Writing to newly grown region without initializing it first.
  • Calling realloc() on memory not obtained from malloc/calloc/realloc (undefined behavior).
  • Not guarding against size multiplication overflow (count * sizeof(T)).
  • Relying on realloc(ptr, 0) return value—prefer free(ptr); ptr = NULL.

Best Practices

• Use a temporary pointer for realloc() and only assign on success.

• Initialize newly allocated regions after growth.

• Update related metadata (size/capacity) atomically with successful reallocation.

• Treat all other aliases/pointers into the block as invalid after reallocation.

• Check for integer overflow before computing byte sizes.

• Prefer free(ptr) + set ptr = NULL over realloc(ptr, 0) for clarity.

Test your knowledge: C Reallocate Memory
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
C MemoryTopic 60 of 64
←PreviousPrevNextNext→