← Back to C Course | Chapter 9: Memory Management | Lesson 5 of 8

C realloc()

realloc changes the size of memory you already borrowed, like swapping your table for a bigger or smaller one. It may move your data to a new place.
Syntax
c
pointer_name = (data_type *) realloc(pointer_name, new_count * sizeof(data_type));

Introduction to realloc()

This is the tool of choice when you don't know an array's final size upfront -- for example, reading an unknown number of lines from a file and growing a dynamic array to fit as you go, doubling its capacity each time it fills up.

Example: Introduction to realloc()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *arr = malloc(2 * sizeof(int));
	arr = realloc(arr, 4 * sizeof(int));
	arr[3] = 99;
	// Print formatted text to the screen
	printf("%d", arr[3]);
	// Release the heap memory so it can be reused
	free(arr);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Expanding Allocated Memory

Because the system may need to find a larger contiguous free block elsewhere in memory, realloc() can change the pointer's actual address -- any old pointers or references into the original block become invalid after a successful call.

Example: Expanding Allocated Memory

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *arr = malloc(2 * sizeof(int));
	arr[0] = 1; arr[1] = 2;
	arr = realloc(arr, 5 * sizeof(int));
	// Print formatted text to the screen
	printf("%d", arr[0]);
	// Release the heap memory so it can be reused
	free(arr);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Shrinking Allocated Memory

The bytes beyond the new smaller size are discarded, but unlike freeing and reallocating from scratch, shrinking in place (when possible) avoids the overhead of copying the remaining data to a new location.

Example: Shrinking Allocated Memory

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *arr = malloc(5 * sizeof(int));
	arr = realloc(arr, 2 * sizeof(int));
	// Print formatted text to the screen
	printf("%zu bytes", 2 * sizeof(int));
	// Release the heap memory so it can be reused
	free(arr);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Handling realloc() failures safely

This failure behavior is exactly why you should never write ptr = realloc(ptr, newSize) directly -- if it fails and returns NULL, you've just overwritten your only reference to the original valid block, causing a memory leak.

Example: Handling realloc() failures safely

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Allocate memory on the heap
	int *arr = malloc(2 * sizeof(int));
	int *temp = realloc(arr, 4 * sizeof(int));
	// Check whether temp != NULL
	if (temp != NULL) {
		arr = temp;
	}
	// Print formatted text to the screen
	printf("%d", arr != NULL);
	// Release the heap memory so it can be reused
	free(arr);
	// Return 0 to signal that the program finished successfully
	return 0;
}

Best practices with realloc()

Since each reallocation potentially involves copying the entire block's contents to a new address, growing an array one element at a time in a loop is much slower than growing it in larger chunks (like doubling capacity) less often.

Example: Best practices with realloc()

c
// Include standard input/output (printf, scanf)
#include <stdio.h>
// Include general utilities (malloc, free, exit)
#include <stdlib.h>
// Program execution starts in main()
int main() {
	// Declare capacity and set it to 2
	int capacity = 2;
	// Allocate memory on the heap
	int *arr = malloc(capacity * sizeof(int));
	capacity *= 2;
	arr = realloc(arr, capacity * sizeof(int));
	// Print formatted text to the screen
	printf("%d", capacity);
	// Release the heap memory so it can be reused
	free(arr);
	// Return 0 to signal that the program finished successfully
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Assigning the result of realloc straight back to the original pointer, which loses the old block if realloc fails and returns NULL.
  2. Using the old pointer after realloc, when the block may have moved.
  3. Forgetting to check realloc for NULL before using the result.
🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.