In this section, we will delve into dynamic memory allocation in C using the malloc and free functions. These functions are essential for managing memory efficiently, especially when the size of the data structure is not known at compile time.
Key Concepts
- Dynamic Memory Allocation: Allocating memory during runtime using functions like 
malloc. - Malloc: Allocates a specified number of bytes and returns a pointer to the first byte.
 - Free: Deallocates the memory previously allocated by 
malloc. 
Malloc
Syntax
- size: The number of bytes to allocate.
 - Return Value: A pointer to the allocated memory, or 
NULLif the allocation fails. 
Example
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *ptr;
    int n, i;
    // Number of elements
    n = 5;
    printf("Enter number of elements: %d\n", n);
    // Dynamically allocate memory using malloc
    ptr = (int*)malloc(n * sizeof(int));
    // Check if the memory has been successfully allocated by malloc
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    } else {
        // Memory has been successfully allocated
        printf("Memory successfully allocated using malloc.\n");
        // Get the elements of the array
        for (i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }
        // Print the elements of the array
        printf("The elements of the array are: ");
        for (i = 0; i < n; ++i) {
            printf("%d ", ptr[i]);
        }
    }
    return 0;
}Explanation
- Include Headers: 
#include <stdlib.h>formallocandfree, and#include <stdio.h>for input/output functions. - Pointer Declaration: 
int *ptr;declares a pointer to an integer. - Memory Allocation: 
ptr = (int*)malloc(n * sizeof(int));allocates memory fornintegers. - Null Check: Checks if 
mallocreturnedNULL, indicating a failure to allocate memory. - Using Allocated Memory: Assigns values to the allocated memory and prints them.
 
Free
Syntax
- ptr: Pointer to the memory to be deallocated.
 
Example
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *ptr;
    int n, i;
    // Number of elements
    n = 5;
    printf("Enter number of elements: %d\n", n);
    // Dynamically allocate memory using malloc
    ptr = (int*)malloc(n * sizeof(int));
    // Check if the memory has been successfully allocated by malloc
    if (ptr == NULL) {
        printf("Memory not allocated.\n");
        exit(0);
    } else {
        // Memory has been successfully allocated
        printf("Memory successfully allocated using malloc.\n");
        // Get the elements of the array
        for (i = 0; i < n; ++i) {
            ptr[i] = i + 1;
        }
        // Print the elements of the array
        printf("The elements of the array are: ");
        for (i = 0; i < n; ++i) {
            printf("%d ", ptr[i]);
        }
        // Free the allocated memory
        free(ptr);
        printf("\nMemory successfully freed.\n");
    }
    return 0;
}Explanation
- Memory Deallocation: 
free(ptr);deallocates the memory previously allocated bymalloc. - Good Practice: Always free dynamically allocated memory to avoid memory leaks.
 
Practical Exercises
Exercise 1: Allocate and Free Memory
Write a program that:
- Allocates memory for an array of 10 integers.
 - Assigns values to the array.
 - Prints the values.
 - Frees the allocated memory.
 
Solution
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr;
    int i;
    // Allocate memory for 10 integers
    arr = (int*)malloc(10 * sizeof(int));
    // Check if memory allocation was successful
    if (arr == NULL) {
        printf("Memory allocation failed.\n");
        return 1;
    }
    // Assign values to the array
    for (i = 0; i < 10; i++) {
        arr[i] = i + 1;
    }
    // Print the values
    printf("Array values: ");
    for (i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    // Free the allocated memory
    free(arr);
    return 0;
}Common Mistakes and Tips
- Not Checking for NULL: Always check if 
mallocreturnsNULLto handle memory allocation failures gracefully. - Double Freeing: Do not call 
freeon the same pointer more than once. - Using Freed Memory: Avoid using memory after it has been freed.
 
Conclusion
In this section, we covered the basics of dynamic memory allocation using malloc and free. Understanding these functions is crucial for efficient memory management in C. Practice the exercises to reinforce your understanding and ensure you handle memory allocation and deallocation correctly.
C Programming Course
Module 1: Introduction to C
- Introduction to Programming
 - Setting Up the Development Environment
 - Hello World Program
 - Basic Syntax and Structure
 
Module 2: Data Types and Variables
Module 3: Control Flow
Module 4: Functions
- Introduction to Functions
 - Function Arguments and Return Values
 - Scope and Lifetime of Variables
 - Recursive Functions
 
Module 5: Arrays and Strings
Module 6: Pointers
Module 7: Structures and Unions
Module 8: Dynamic Memory Allocation
Module 9: File Handling
- Introduction to File Handling
 - Reading and Writing Files
 - File Positioning
 - Error Handling in File Operations
 
Module 10: Advanced Topics
Module 11: Best Practices and Optimization
- Code Readability and Documentation
 - Debugging Techniques
 - Performance Optimization
 - Security Considerations
 
