Dynamic Memory Management
malloc(), calloc(), realloc() and free()

Lecture 21 - Unit V: File Handling & Memory Management

BTech First Semester - C Programming

Instructor: Mohsin F. Dar

Designation: Assistant Professor

Department: Cloud & Software Operations Cluster | SOCS

University: UPES

Memory Management in C

Types of Memory Allocation

📊 Static Memory

  • Fixed size at compile time
  • Allocated on Stack
  • Automatic deallocation
  • Limited flexibility

🚀 Dynamic Memory

  • Size determined at runtime
  • Allocated on Heap
  • Manual deallocation required
  • High flexibility
Key Point: Dynamic memory allocation allows programs to request memory during execution, making them more flexible and efficient.
Header File Required: #include <stdlib.h>
Lecture 21 | SOCS, UPES
Memory Allocation Visualization

How Memory is Organized

Stack Memory

Local Variables
Function Calls
Static Arrays

✓ Auto managed
✓ Fixed size
✓ Fast access

Heap Memory

malloc()
calloc()
realloc()
free()

✓ Manual control
✓ Dynamic size
✓ Flexible

Remember: Stack is managed automatically, Heap requires manual management using malloc/calloc/realloc/free.
Lecture 21 | SOCS, UPES
Quick Function Summary

All Four Functions at a Glance

Function Purpose Initialization Parameters
malloc() Allocate memory Garbage values 1 - Total size in bytes
calloc() Allocate & initialize Zero (0) 2 - Count and size
realloc() Resize memory Preserves old data 2 - Pointer and new size
free() Deallocate memory N/A 1 - Pointer to free

Return Values:

  • malloc/calloc/realloc: Return void* pointer (cast to appropriate type)
  • Success: Returns pointer to allocated memory
  • Failure: Returns NULL
  • free(): Returns nothing (void)
Lecture 21 | SOCS, UPES
Common Errors to Avoid

Top 5 Common Mistakes

1. Not Checking for NULL
int *ptr = (int*) malloc(sizeof(int)); *ptr = 5; // CRASH if malloc failed!
2. Memory Leak - Forgetting to Free
for (int i = 0; i < 1000; i++) { int *ptr = malloc(1000); // No free() - leaking 1MB! }
3. Double Free
free(ptr); free(ptr); // ERROR: Undefined behavior!
4. Using After Free
free(ptr); printf("%d", *ptr); // Dangling pointer!
5. Wrong Size Calculation
int *arr = malloc(10); // Wrong! Should be 10*sizeof(int)
Lecture 21 | SOCS, UPES
Best Practices for Dynamic Memory

Golden Rules

✅ DO

  • Always check if pointer is NULL after allocation
  • Use sizeof() operator for size calculation
  • Free memory when no longer needed
  • Set pointer to NULL after freeing
  • Use calloc() when zero initialization is needed
  • Keep track of allocated memory

❌ DON'T

  • Don't use memory before checking NULL
  • Don't forget to free allocated memory
  • Don't free the same pointer twice
  • Don't use pointer after freeing
  • Don't assume allocation always succeeds
  • Don't hardcode sizes, use sizeof()
Memory Management Mantra:
"Every malloc/calloc/realloc must have a corresponding free!"
Lecture 21 | SOCS, UPES
Real-World Example: Student Database
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { int roll_no; char name[50]; float marks; }; int main() { struct Student *students; int n, i; printf("Enter number of students: "); scanf("%d", &n); // Allocate memory for n students students = (struct Student*) calloc(n, sizeof(struct Student)); if (students == NULL) { printf("Memory allocation failed!\n"); return 1; } // Input student data for (i = 0; i < n; i++) { printf("\nStudent %d:\n", i+1); printf("Roll No: "); scanf("%d", &students[i].roll_no); printf("Name: "); scanf("%s", students[i].name); printf("Marks: "); scanf("%f", &students[i].marks); } // Display student data printf("\n--- Student Records ---\n"); for (i = 0; i < n; i++) { printf("%d\t%s\t%.2f\n", students[i].roll_no, students[i].name, students[i].marks); } free(students); // Free allocated memory return 0; }
Lecture 21 | SOCS, UPES
Advantages & Disadvantages

Dynamic Memory Management

✅ Advantages

  • Flexibility: Size determined at runtime
  • Efficiency: Allocate only what you need
  • Memory Reuse: Can free and reallocate
  • Large Data: Can handle large data structures
  • Data Structures: Essential for linked lists, trees, graphs
  • Scalability: Program adapts to available memory

❌ Disadvantages

  • Manual Management: Must free memory manually
  • Memory Leaks: Risk if free() not called
  • Fragmentation: Memory can become fragmented
  • Slower: Heap allocation slower than stack
  • Complexity: More code and error-prone
  • Debugging: Memory bugs hard to find
When to Use Dynamic Memory?
Use when size is unknown at compile time, working with large data, or building complex data structures like linked lists, trees, or graphs.
Lecture 21 | SOCS, UPES
Common Interview Questions

Frequently Asked Questions

Q1: What happens if malloc() fails?
A: It returns NULL. Always check for NULL before using the pointer.
Q2: Difference between malloc() and calloc()?
A: malloc() doesn't initialize memory (garbage values), calloc() initializes to zero. calloc() takes two parameters (count, size), malloc() takes one (total size).
Q3: Can we increase array size after declaration?
A: Static arrays: No. Dynamic arrays: Yes, using realloc().
Q4: What is a dangling pointer?
A: A pointer that points to freed/deallocated memory. Accessing it causes undefined behavior.
Q5: Why set pointer to NULL after free()?
A: To avoid dangling pointer issues. NULL pointer checks prevent accidental access to freed memory.
Lecture 21 | SOCS, UPES
Practice Problems

Try These Yourself!

Problem 1: Basic Allocation

Write a program to dynamically allocate memory for n integers, input values, find their sum, and free the memory.

Problem 2: Matrix Allocation

Dynamically allocate a 2D matrix of size m×n, input values, display the matrix, and free all allocated memory.

Problem 3: String Array

Create a dynamic array of strings to store n names. Input the names, sort them alphabetically, display, and free memory.

Problem 4: Memory Reallocation

Start with an array of 5 elements. Take user input to add more elements. Use realloc() to expand the array as needed.

Problem 5: Structure Array

Create a dynamic array of Employee structures with fields: ID, Name, Salary. Implement add, display, and delete operations.

Lecture 21 | SOCS, UPES
Summary & Key Takeaways

What We Learned Today

🔹 malloc() - Allocates memory without initialization
• Syntax: malloc(size_in_bytes)
🔹 calloc() - Allocates and initializes to zero
• Syntax: calloc(count, size_of_each)
🔹 realloc() - Resizes previously allocated memory
• Syntax: realloc(pointer, new_size)
🔹 free() - Deallocates memory
• Syntax: free(pointer)
⚠️ Remember:
• Always check for NULL after allocation
• Always free allocated memory
• Set pointers to NULL after freeing
• Use sizeof() for correct size calculation
Lecture 21 | SOCS, UPES
Thank You!

Questions?

Lecture 21 - Unit V

Dynamic Memory Management

malloc() • calloc() • realloc() • free()

Mohsin F. Dar

Assistant Professor

Cloud & Software Operations Cluster | SOCS

UPES

Next Lecture: More topics from Unit V

Lecture 21 | SOCS, UPES
1 / 21
malloc() - Memory Allocation

malloc() Function

malloc stands for Memory Allocation

Syntax:

void* malloc(size_t size);

Characteristics:

Example:

int *ptr; ptr = (int*) malloc(5 * sizeof(int)); if (ptr == NULL) { printf("Memory allocation failed!\n"); return 1; }
Lecture 21 | SOCS, UPES
calloc() - Contiguous Allocation

calloc() Function

calloc stands for Contiguous Allocation

Syntax:

void* calloc(size_t num, size_t size);

Characteristics:

Example:

int *ptr; ptr = (int*) calloc(5, sizeof(int)); if (ptr == NULL) { printf("Memory allocation failed!\n"); return 1; } // All 5 integers initialized to 0
Lecture 21 | SOCS, UPES
malloc() vs calloc() Comparison

Key Differences

Feature malloc() calloc()
Full Form Memory Allocation Contiguous Allocation
Arguments One (total bytes) Two (number, size)
Initialization Garbage values Zero initialization
Speed Faster Slower
Syntax malloc(size) calloc(n, size)
When to use which?
• Use malloc() when initialization is not needed
• Use calloc() when you need zero-initialized memory
Lecture 21 | SOCS, UPES
realloc() - Memory Reallocation

realloc() Function

realloc stands for Re-Allocation - Used to resize previously allocated memory

Syntax:

void* realloc(void* ptr, size_t new_size);

Characteristics:

Example:

int *ptr = (int*) malloc(5 * sizeof(int)); // Need more space? Use realloc ptr = (int*) realloc(ptr, 10 * sizeof(int)); if (ptr == NULL) { printf("Reallocation failed!\n"); }
Lecture 21 | SOCS, UPES
free() - Memory Deallocation

free() Function

Critical: Always free dynamically allocated memory to prevent memory leaks!

Syntax:

void free(void* ptr);

Important Points:

Example:

int *ptr = (int*) malloc(5 * sizeof(int)); // Use the memory... free(ptr); // Deallocate memory ptr = NULL; // Good practice: avoid dangling pointer
Lecture 21 | SOCS, UPES
Complete Working Example
#include <stdio.h> #include <stdlib.h> int main() { int *arr, n, i; printf("Enter number of elements: "); scanf("%d", &n); // Allocate memory using malloc arr = (int*) malloc(n * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed!\n"); return 1; } // Input elements for (i = 0; i < n; i++) { scanf("%d", &arr[i]); } // Display elements for (i = 0; i < n; i++) { printf("%d ", arr[i]); } free(arr); // Free allocated memory return 0; }
Lecture 21 | SOCS, UPES
Common Mistakes & Memory Leaks

What is a Memory Leak?

A memory leak occurs when dynamically allocated memory is not freed, causing the program to consume more memory over time.

❌ Bad Example (Memory Leak):

void badFunction() { int *ptr = (int*) malloc(100 * sizeof(int)); // Use the memory... // Oops! Forgot to free(ptr) } // Memory leak! 400 bytes lost forever

✅ Good Example:

void goodFunction() { int *ptr = (int*) malloc(100 * sizeof(int)); if (ptr == NULL) return; // Use the memory... free(ptr); // Always free! ptr = NULL; }
Lecture 21 | SOCS, UPES
Dangling Pointer Problem

What is a Dangling Pointer?

A dangling pointer points to memory that has been freed. Accessing it leads to undefined behavior.

Problem Example:

int *ptr = (int*) malloc(sizeof(int)); *ptr = 10; free(ptr); // Memory is freed printf("%d", *ptr); // DANGER! Dangling pointer access

Solution:

int *ptr = (int*) malloc(sizeof(int)); *ptr = 10; free(ptr); ptr = NULL; // Set to NULL after freeing if (ptr != NULL) { // Always check before use printf("%d", *ptr); }
Best Practice: Always set pointers to NULL after freeing them.
Lecture 21 | SOCS, UPES
Practical Application: Dynamic Array

Creating a Dynamically Resizable Array:

#include <stdio.h> #include <stdlib.h> int main() { int *arr, size = 5, new_size = 10; // Initial allocation arr = (int*) calloc(size, sizeof(int)); // Fill array for (int i = 0; i < size; i++) { arr[i] = i + 1; } printf("Original array: "); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } // Resize array arr = (int*) realloc(arr, new_size * sizeof(int)); printf("\nResized to %d elements\n", new_size); free(arr); return 0; }
Lecture 21 | SOCS, UPES