malloc() / calloc() / realloc() / free()
Allocates memory as needed during program execution and releases it when done. Use these functions when you need to determine array sizes at runtime or work with large amounts of data. These functions are declared in <stdlib.h>.
Syntax
#include <stdlib.h> // Allocates size bytes of memory (uninitialized). void *malloc(size_t size); // Allocates num elements of size bytes each, initialized to zero. void *calloc(size_t num, size_t size); // Resizes a previously allocated memory block to new_size bytes. void *realloc(void *ptr, size_t new_size); // Frees previously allocated memory. void free(void *ptr);
Dynamic Memory Functions
| Function | Description |
|---|---|
| malloc(size) | Allocates the specified number of bytes from the heap. The initial value is indeterminate. Returns NULL if allocation fails. |
| calloc(num, size) | Allocates num elements of size bytes each and initializes all bytes to zero. Useful for initializing integer arrays. |
| realloc(ptr, new_size) | Resizes the memory block pointed to by ptr to new_size bytes. If necessary, moves the block to a new location and copies the original contents. |
| free(ptr) | Frees memory allocated by malloc, calloc, or realloc. Passing NULL is safe. Do not free a pointer that has already been freed. |
Sample Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
// Allocate an array whose size is determined at runtime.
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
int *arr = malloc(sizeof(int) * n);
if (arr == NULL) {
fprintf(stderr, "Memory allocation failed.\n");
return 1;
}
// Assign values and print them.
for (int i = 0; i < n; i++) {
arr[i] = (i + 1) * 10;
}
for (int i = 0; i < n; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// Always free the memory when you are done with it.
free(arr);
arr = NULL; // Assign NULL to prevent a dangling pointer.
// calloc initializes all elements to zero.
int *zeros = calloc(5, sizeof(int));
for (int i = 0; i < 5; i++) {
printf("%d ", zeros[i]); // All values are printed as 0.
}
printf("\n");
free(zeros);
// Use realloc to dynamically grow an array.
int *buf = malloc(sizeof(int) * 3);
buf[0] = 1; buf[1] = 2; buf[2] = 3;
int *new_buf = realloc(buf, sizeof(int) * 6);
if (new_buf == NULL) {
free(buf);
return 1;
}
buf = new_buf;
buf[3] = 4; buf[4] = 5; buf[5] = 6;
for (int i = 0; i < 6; i++) {
printf("%d ", buf[i]); // Prints "1 2 3 4 5 6".
}
printf("\n");
free(buf);
return 0;
}
Notes
Dynamically allocated memory is placed in a region called the "heap." Unlike automatic variables on the stack, heap memory is not released until you explicitly call free(). Failing to free allocated memory causes a "memory leak," where memory usage grows continuously over the lifetime of the program. Always free memory when you are done with it.
Using freed memory (a "dangling pointer") or freeing the same memory twice (a "double free") causes serious bugs. Always assign NULL to a pointer after freeing it.
When realloc() fails, it does not free the original pointer, so always check the return value with a separate variable before reassigning. For related functions, see also sizeof.
If you find any errors or copyright issues, please contact us.