Dynamic Memory
Duration: 55 min
Dynamic memory allocation allows you to allocate memory at runtime. This is essential for creating data structures of unknown size and managing memory efficiently. C provides malloc, calloc, realloc, and free for dynamic memory management.
malloc Function
#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocate memory for 5 integers
int *ptr = (int*)malloc(5 * sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Use the allocated memory
for (int i = 0; i < 5; i++) {
ptr[i] = i * 10;
}
// Print values
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// Free the memory
free(ptr);
ptr = NULL; // Good practice
return 0;
}calloc Function
#include <stdio.h>
#include <stdlib.h>
int main() {
// calloc: allocates and initializes to 0
int *ptr = (int*)calloc(5, sizeof(int));
if (ptr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// All elements are initialized to 0
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]); // 0 0 0 0 0
}
printf("\n");
free(ptr);
ptr = NULL;
return 0;
}realloc Function
#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocate initial memory
int *ptr = (int*)malloc(3 * sizeof(int));
ptr[0] = 10;
ptr[1] = 20;
ptr[2] = 30;
// Resize to 5 integers
ptr = (int*)realloc(ptr, 5 * sizeof(int));
if (ptr == NULL) {
printf("Reallocation failed\n");
return 1;
}
ptr[3] = 40;
ptr[4] = 50;
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
free(ptr);
ptr = NULL;
return 0;
}Memory Leaks
#include <stdio.h>
#include <stdlib.h>
// BAD: Memory leak
void leaky_function() {
int *ptr = (int*)malloc(100 * sizeof(int));
// ... use ptr ...
// Forgot to free!
}
// GOOD: Proper memory management
void good_function() {
int *ptr = (int*)malloc(100 * sizeof(int));
// ... use ptr ...
free(ptr);
ptr = NULL;
}
int main() {
good_function();
return 0;
}Dynamic Arrays
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter array size: ");
scanf("%d", &n);
// Allocate array of size n
int *arr = (int*)malloc(n * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Input values
for (int i = 0; i < n; i++) {
printf("Enter element %d: ", i);
scanf("%d", &arr[i]);
}
// Print values
printf("Array: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
arr = NULL;
return 0;
}Dynamic 2D Arrays
#include <stdio.h>
#include <stdlib.h>
int main() {
int rows = 3, cols = 4;
// Allocate array of pointers
int **matrix = (int**)malloc(rows * sizeof(int*));
// Allocate each row
for (int i = 0; i < rows; i++) {
matrix[i] = (int*)malloc(cols * sizeof(int));
}
// Initialize and print
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j;
printf("%d ", matrix[i][j]);
}
printf("\n");
}
// Free memory
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
return 0;
}Dynamic Structures
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int id;
char name[50];
float salary;
} Employee;
int main() {
int n;
printf("Enter number of employees: ");
scanf("%d", &n);
// Allocate array of structures
Employee *employees = (Employee*)malloc(n * sizeof(Employee));
if (employees == NULL) {
printf("Memory allocation failed\n");
return 1;
}
// Input data
for (int i = 0; i < n; i++) {
printf("Employee %d ID: ", i + 1);
scanf("%d", &employees[i].id);
printf("Name: ");
scanf("%s", employees[i].name);
printf("Salary: ");
scanf("%f", &employees[i].salary);
}
// Print data
for (int i = 0; i < n; i++) {
printf("%d %s %.2f\n",
employees[i].id,
employees[i].name,
employees[i].salary);
}
free(employees);
employees = NULL;
return 0;
}Best Practices
#include <stdio.h>
#include <stdlib.h>
int main() {
// 1. Always check if allocation succeeded
int *ptr = (int*)malloc(100 * sizeof(int));
if (ptr == NULL) {
printf("Allocation failed\n");
return 1;
}
// 2. Use sizeof to avoid hardcoding sizes
// Good: malloc(n * sizeof(int))
// Bad: malloc(n * 4)
// 3. Free memory when done
free(ptr);
// 4. Set to NULL after freeing
ptr = NULL;
// 5. Don't use memory after freeing
// printf("%d\n", *ptr); // DANGER!
return 0;
}Quiz 1: malloc
❓ What does malloc return if allocation fails?
Quiz 2: calloc vs malloc
❓ What is the main difference between calloc and malloc?
Quiz 3: Memory Leak
❓ What is a memory leak?
Quiz 4: realloc
❓ What does realloc do?
Quiz 5: sizeof in malloc
❓ Why use sizeof in malloc? int *ptr = (int*)malloc(n * sizeof(int))