In C, the realloc
function is used to resize a previously allocated block of memory, enabling you to increase or decrease its size during runtime. This is particularly useful when you need to expand or shrink the size of an existing memory allocation, without losing the original data.
1. realloc
Function Overview
- Declared in the
<stdlib.h>
header file. - Used to resize an already dynamically allocated memory block.
- Can be used to extend or reduce the size of a previously allocated memory block.
- If the resizing is successful,
realloc
returns a pointer to the newly allocated memory. If not, it returnsNULL
.
2. Syntax
void* realloc(void* ptr, size_t new_size);
ptr
: A pointer to the memory previously allocated usingmalloc
,calloc
, orrealloc
. Ifptr
isNULL
,realloc
behaves likemalloc
.new_size
: The new size of the memory block in bytes.
3. How realloc
Works
- If
ptr
isNULL
,realloc
acts likemalloc
and allocatesnew_size
bytes. - If
new_size
is 0 andptr
is notNULL
,realloc
behaves likefree
and releases the memory. - If the new memory block is larger,
realloc
copies the old content to the new block and may fill additional memory with undefined values. - The function may return a new memory address if the old memory block cannot be resized in place. In this case, the data is copied to the new location, and the old block is freed.
4. Usage Example
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n = 5;
// Allocate initial memory for 5 integers
arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Initial memory allocation failed!\n");
return 1;
}
// Assign values to the allocated memory
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
// Print initial values
printf("Initial array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Resize the array to hold 10 integers
n = 10;
arr = (int *)realloc(arr, n * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed!\n");
return 1;
}
// Assign new values to the additional memory
for (int i = 5; i < n; i++) {
arr[i] = i + 1;
}
// Print the updated array
printf("Resized array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free the allocated memory
free(arr);
return 0;
}
Explanation:
- Initial Allocation: The array is allocated for 5 integers using
malloc
. - Memory Reallocation: The array is resized using
realloc
to hold 10 integers. - Using Additional Memory: New values are assigned to the extra memory locations.
- Free Memory: The entire block is freed using
free
.
Output Example:
Initial array: 1 2 3 4 5
Resized array: 1 2 3 4 5 6 7 8 9 10
5. Important Considerations
Data Preservation:
realloc
preserves the data in the original memory block when resizing, but if a new memory location is required, it moves the data to the new block.- Be careful, as the old pointer (
ptr
) may become invalid ifrealloc
moves the memory to a new location.
Memory Leaks:
- If
realloc
returnsNULL
due to a failure (e.g., insufficient memory), the original block remains allocated, potentially leading to a memory leak if not handled properly. - Always assign the result of
realloc
to a temporary pointer first, then check forNULL
.
Example:
int *temp = realloc(arr, new_size); if (temp == NULL) { // Handle allocation failure } else { arr = temp; // Update the pointer if allocation succeeded }
- If
Shrinking Memory:
- If
new_size
is smaller than the original size, the extra memory is deallocated. - However, be careful with accessing memory beyond the new size, as this leads to undefined behavior.
- If
Freeing Memory:
- Memory allocated or reallocated by
realloc
must eventually be freed usingfree
to avoid memory leaks.
- Memory allocated or reallocated by
6. Example: Shrinking Memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n = 10;
// Allocate memory for 10 integers
arr = (int *)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Assign values to the allocated memory
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
// Shrink the memory to hold only 5 integers
n = 5;
arr = (int *)realloc(arr, n * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed!\n");
return 1;
}
// Print the resized array
printf("Shrunk array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// Free the allocated memory
free(arr);
return 0;
}
Output Example:
Shrunk array: 1 2 3 4 5
Summary
realloc
is used to resize memory that has already been dynamically allocated.- It allows for both expanding and shrinking the allocated memory block.
- Always check the return value of
realloc
to ensure memory allocation was successful. - Be careful to prevent memory leaks by properly handling failures (
NULL
return value). - If
realloc
moves the memory block, it automatically copies the contents of the old block to the new one, which might result in a new memory address.
Using realloc
effectively helps manage dynamically changing memory needs in C, making it useful for dynamic data structures like dynamic arrays or linked lists, where the number of elements may vary during runtime.