Dynamic Memory Allocation in C – malloc, calloc, free

1️⃣ Why Dynamic Memory?

In C, when you declare an array or variable, its size must be known at compile time:

int numbers[100];  // Fixed size

But what if:

  • You don’t know the size in advance (e.g., user input)?
  • You want to allocate memory at runtime?

👉 Dynamic memory allocation solves this problem.


2️⃣ Key Functions

FunctionWhat It Does
mallocAllocates a block of memory (uninitialized).
callocAllocates and also initializes the block to zero.
freeFrees the previously allocated memory to avoid memory leaks.

All these functions are in the stdlib.h library.


3️⃣ malloc – Memory Allocation

Syntax:

ptr = (castType *) malloc(size_in_bytes);

🛠 Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr;
    ptr = (int *) malloc(5 * sizeof(int));  // Allocate memory for 5 integers

    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    // Assign and print values
    for (int i = 0; i < 5; i++) {
        ptr[i] = (i + 1) * 10;
        printf("%d ", ptr[i]);
    }

    free(ptr);  // Free the allocated memory
    return 0;
}

🔍 Key Points:

  • malloc(5 * sizeof(int)): Allocates space for 5 integers.
  • Memory is uninitialized → it may contain garbage values if accessed before setting.
  • Always check if the pointer is NULL (allocation failed).

4️⃣ calloc – Contiguous Allocation

Syntax:

ptr = (castType *) calloc(number_of_elements, size_of_each_element);

🛠 Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr;
    ptr = (int *) calloc(5, sizeof(int));  // Allocate space for 5 integers (initialized to 0)

    if (ptr == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }

    // Print default values
    for (int i = 0; i < 5; i++) {
        printf("%d ", ptr[i]);  // Will print 0s
    }

    free(ptr);  // Free the allocated memory
    return 0;
}

🔍 Key Points:

  • calloc(5, sizeof(int)): Allocates space for 5 integers.
  • All elements are initialized to 0.

5️⃣ free – Deallocating Memory

Always use free() to release memory allocated by malloc or calloc.
Failing to do so causes a memory leak.

free(ptr);

After free(), the pointer becomes dangling (it points to a memory you no longer own). Best practice is:

free(ptr);
ptr = NULL;  // Make pointer safe

6️⃣ Difference Between malloc and calloc

Featuremalloccalloc
InitializationUninitialized (contains garbage values)Initializes all bytes to zero
ParametersTotal size in bytesNumber of elements & size of each element
SpeedSlightly fasterSlightly slower (due to zeroing)
Use caseWhen you plan to initialize data yourselfWhen you need zero-initialized memory

7️⃣ When to Use Dynamic Memory

Use CaseWhy Dynamic Memory?
Array size is not known at compile timeAllocate memory at runtime based on user input or calculations.
Large data structures (linked lists, trees)Need flexible, growable structures.
Save stack spaceHeap allocation prevents stack overflow for large data.
Resizable buffers (e.g., file reading)Dynamically increase buffer size as needed.

8️⃣ Example: Dynamically Allocated 2D Array (Matrix)

#include <stdio.h>
#include <stdlib.h>

int main() {
    int rows = 3, cols = 4;
    int **matrix;

    // Allocate memory for rows
    matrix = (int **) malloc(rows * sizeof(int *));
    for (int i = 0; i < rows; i++) {
        matrix[i] = (int *) malloc(cols * sizeof(int));  // Columns
    }

    // Fill the matrix
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = i + j;
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    // Free memory
    for (int i = 0; i < rows; i++) {
        free(matrix[i]);  // Free each row
    }
    free(matrix);  // Free row pointers

    return 0;
}

🔧 Common Mistakes to Avoid

  • ❌ Forgetting to check if malloc or calloc returned NULL.
  • ❌ Forgetting to free() memory.
  • ❌ Accessing memory after it’s freed (undefined behavior).
  • ❌ Memory leaks: Allocating memory but never freeing it.

✅ Conclusion

  • Use malloc when you need uninitialized memory.
  • Use calloc when you need zero-initialized memory.
  • Always free the memory after use.
  • Dynamic memory allows flexible, efficient programs, but manual management is your responsibility.

💡 Next step idea: Learn about realloc() to resize dynamically allocated memory.

Feedback Display

Learner Reviews