5.4) Dynamic memory allocation in C
Dynamic memory allocation is an essential concept in C programming that lets you allocate memory for data structures at runtime.
It’s particularly useful when you don’t know the size of data in advance.
Here’s a detailed explanation with code examples:
Table of Contents
malloc()
The malloc() function (short for “memory allocation”) is used to allocate memory dynamically from the heap. It takes the size in bytes as an argument and returns a pointer to the allocated memory.
Example: Using malloc() to Allocate Memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
// Allocate memory for an integer
ptr = (int *)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1; // Exit the program
}
*ptr = 42;
printf("Value stored at ptr: %d\n", *ptr);
// Free the allocated memory
free(ptr);
return 0;
}
Output:
Value stored at ptr: 42
Allocating Memory for Arrays
You can use malloc()
to allocate memory for arrays dynamically. This is especially useful when you don’t know the array size beforehand.
Example: Using malloc() for Dynamic Arrays
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
int *arr;
printf("Enter the size of the array: ");
scanf("%d", &size);
// Allocate memory for an array of integers
arr = (int *)malloc(size * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1; // Exit the program
}
for (int i = 0; i < size; i++) {
arr[i] = i * 10;
printf("Element %d: %d\n", i, arr[i]);
}
// Free the allocated memory
free(arr);
return 0;
}
Output (for input size = 3):
Enter the size of the array: 3
Element 0: 0
Element 1: 10
Element 2: 20
calloc()
The calloc() function is used to allocate memory for an array of elements. It takes two arguments: the number of elements and the size of each element.
Example: Using calloc() for Dynamic Arrays
#include <stdio.h>
#include <stdlib.h>
int main() {
int size;
int *arr;
printf("Enter the size of the array: ");
scanf("%d", &size);
// Allocate memory for an array of integers using calloc
arr = (int *)calloc(size, sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1; // Exit the program
}
for (int i = 0; i < size; i++) {
arr[i] = i * 5;
printf("Element %d: %d\n", i, arr[i]);
}
// Free the allocated memory
free(arr);
return 0;
}
Output (for input size = 4):
Enter the size of the array: 4
Element 0: 0
Element 1: 5
Element 2: 10
Element 3: 15
realloc()
The realloc() function is used to resize dynamically allocated memory. It takes a pointer to the previously allocated memory and the new size as arguments.
Example: Using realloc() to Resize Memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
// Allocate memory for an array of integers
arr = (int *)malloc(3 * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1; // Exit the program
}
for (int i = 0; i < 3; i++) {
arr[i] = i + 1;
printf("Element %d: %d\n", i, arr[i]);
}
// Resize the array using realloc
arr = (int *)realloc(arr, 5 * sizeof(int));
if (arr != NULL) {
for (int i = 3; i < 5; i++) {
arr[i] = i + 1;
printf("Element %d: %d\n", i, arr[i]);
}
}
// Free the allocated memory
free(arr);
return 0;
}
Output:
Element 0: 1
Element 1: 2
Element 2: 3
Element 3: 4
Element 4: 5
free()
The free() function in C is used to deallocate memory that was previously allocated using functions like malloc()
, calloc()
, or realloc()
. Properly using free()
is crucial to prevent memory leaks in your program. Here’s an explanation of free()
along with an example:
Function: void free(void *ptr)
free()
takes a single argument, which is a pointer to the memory block you want to deallocate.- After calling
free()
, the memory pointed to by the pointer becomes available for reuse by the system.
Example: Using free() to Deallocate Memory
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
// Allocate memory for an integer
ptr = (int *)malloc(sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1; // Exit the program
}
*ptr = 42;
printf("Value stored at ptr: %d\n", *ptr);
// Deallocate the allocated memory using free
free(ptr);
// Accessing memory after deallocation is undefined behavior
// printf("Value after deallocation: %d\n", *ptr);
return 0;
}
Explanation:
- In this example, memory is allocated using
malloc()
to store an integer. - After using the allocated memory, it’s important to free it using the
free()
function to avoid memory leaks. - Accessing the memory after it has been deallocated using
free()
results in undefined behavior and should be avoided.
Keep these points in mind when using free():
- Only Free Allocated Memory: You should only use
free()
to deallocate memory that was previously allocated using functions likemalloc()
,calloc()
, orrealloc()
. Attempting to free memory that wasn’t allocated dynamically or has already been freed leads to undefined behavior. - Deallocate All Allocated Memory: Make sure to free all dynamically allocated memory before your program exits. This ensures that the memory is properly returned to the system and prevents memory leaks.
- Use After Free: Accessing memory that has been deallocated using
free()
leads to undefined behavior and can result in crashes or unexpected behavior. Always ensure you don’t use the memory after it has been freed.
Dynamic memory allocation is a powerful tool, but proper memory management using functions like free() is essential to maintain the stability and reliability of your C programs.
Dynamic memory allocation allows you to manage memory more flexibly, especially when you don’t know the exact memory requirements at compile time. Remember to always free the dynamically allocated memory using free() to prevent memory leaks in your program.