DevAcademia
C++C#CPythonJava
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz
  • C Basics

  • Introduction to C
  • Getting Started with C
  • C Syntax
  • C Output
  • C Comments
  • C Variables
  • C Data Types
  • C Constants
  • C Operators
  • C Booleans
  • C If...Else Statements
  • C Switch Statement
  • C While Loops
  • C For Loops
  • C Break and Continue
  • C Strings
  • C User Input
  • C Memory Address
  • C Pointers
  • C Files
  • C Functions

  • C Functions
  • C Function Parameters
  • C Scope
  • C Function Declaration
  • C Recursion
  • C Math Functions
  • C Structures

  • C Structures
  • C Structs & Pointers
  • C Unions
  • C Enums

  • C Enums
  • C Memory

  • C Allocate Memory
  • C Access Memory
  • C Reallocate Memory
  • C Deallocate Memory
  • C Structs and Memory
  • C Memory Example
  • C Quiz

  • C Quiz

Loading C tutorial…

Loading content
C MemoryTopic 58 of 64
←PreviousPrevNextNext→

C Allocate Memory

Introduction to Memory Allocation

Memory allocation is the process of reserving memory space during program execution. In C, dynamic memory allocation allows programs to request memory from the heap at runtime, enabling flexible data structures and efficient memory usage.

Key benefits of dynamic memory allocation:

- Memory size can be determined at runtime

- Memory can be resized as needed

- Memory persists beyond function scope

- Enables creation of complex data structures

Memory Allocation Functions

FunctionDescriptionSyntaxReturn Value
malloc()Allocates raw memoryvoid* malloc(size_t size)Pointer to allocated memory or NULL
calloc()Allocates and zero-initializes memoryvoid* calloc(size_t num, size_t size)Pointer to allocated memory or NULL
realloc()Resizes existing allocationvoid* realloc(void* ptr, size_t size)Pointer to resized memory or NULL (original block remains valid on failure)
free()Deallocates previously allocated memoryvoid free(void* ptr)None (void)

malloc() - Memory Allocation

⚠️ Warning: Always check if malloc() returns NULL. Unchecked NULL pointers lead to undefined behavior when dereferenced.
Example
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *numbers;
    size_t count = 5;
    
    // Allocate memory for 5 integers
    numbers = malloc(count * sizeof *numbers);
    
    // CRITICAL: Check if allocation succeeded
    if (numbers == NULL) {
        printf("Memory allocation failed!\n");
        return 1; // Exit with error code
    }
    
    printf("Memory allocated successfully at address: %p\n", (void*)numbers);
    printf("Allocated size: %zu bytes\n", count * sizeof *numbers);
    
    // Initialize the allocated memory
    for (size_t i = 0; i < count; i++) {
        numbers[i] = (int)((i + 1) * 10); // Values: 10, 20, 30, 40, 50
    }
    
    // Use the allocated memory
    printf("Array values: ");
    for (size_t i = 0; i < count; i++) {
        printf("%d ", numbers[i]);
    }
    printf("\n");
    
    // Don't forget to free the memory later!
    free(numbers);
    
    return 0;
}
Output
Memory allocated successfully at address: 0x55a1b2c3d4e0
Allocated size: 20 bytes
Array values: 10 20 30 40 50

calloc() - Contiguous Allocation

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

int main(void) {
    float *scores;
    int studentCount = 4;
    
    // Allocate and initialize memory to zero
    scores = calloc((size_t)studentCount, sizeof *scores);
    
    if (scores == NULL) {
        printf("Memory allocation failed!\n");
        return 1;
    }
    
    printf("calloc() initialized values: ");
    for (int i = 0; i < studentCount; i++) {
        printf("%.1f ", scores[i]); // All 0.0
    }
    printf("\n");
    
    // Assign values
    scores[0] = 85.5f;
    scores[1] = 92.0f;
    scores[2] = 78.5f;
    scores[3] = 88.0f;
    
    printf("After assignment: ");
    for (int i = 0; i < studentCount; i++) {
        printf("%.1f ", scores[i]);
    }
    printf("\n");
    
    free(scores);
    return 0;
}
Output
calloc() initialized values: 0.0 0.0 0.0 0.0
After assignment: 85.5 92.0 78.5 88.0
ℹ️ Note: calloc() is preferred when you need zero-initialized memory or when allocating arrays of elements.

Allocation Best Practices

  • Always check if allocation functions return NULL
  • Prefer `sizeof *ptr` over `sizeof(type)` to avoid mismatches
  • Do NOT cast the return value of malloc/calloc/realloc in C
  • Use calloc() when zero-initialization is required
  • Calculate size carefully to avoid integer overflow
  • Consider memory alignment requirements for your platform

Common Allocation Errors

⚠️ Warning: These examples demonstrate common pitfalls. Always follow best practices to avoid these errors.
Example
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    // ERROR: Forgetting to check for NULL
    int *badPtr = malloc(1000000000ULL * sizeof *badPtr);
    // If allocation fails, badPtr is NULL -> dereferencing would crash
    // if (badPtr) { /* use badPtr */ }
    
    // ERROR: Using memory before allocation
    int *uninitialized;
    // printf("%d\n", *uninitialized); // UNDEFINED BEHAVIOR!
    
    // ERROR: Wrong size calculation
    int *wrongSize = malloc(5); // Should be 5 * sizeof *wrongSize
    
    // ERROR: Memory leak - allocating without freeing
    int *leaky = malloc(10 * sizeof *leaky);
    // Forgot to free(leaky) -> MEMORY LEAK!
    
    // Clean up anything we actually allocated for this demo (avoid compiler warnings)
    free(badPtr);
    free(wrongSize);
    free(leaky); // (Still illustrates that forgetting this would leak.)
    
    return 0;
}

Advanced Allocation Patterns

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

// Allocate a 2D array dynamically
int **create2DArray(int rows, int cols) {
    int **array = malloc((size_t)rows * sizeof *array);
    if (array == NULL) return NULL;
    
    for (int i = 0; i < rows; i++) {
        array[i] = malloc((size_t)cols * sizeof *array[i]);
        if (array[i] == NULL) {
            // Clean up previously allocated rows
            for (int j = 0; j < i; j++) {
                free(array[j]);
            }
            free(array);
            return NULL;
        }
    }
    return array;
}

int main(void) {
    int rows = 3, cols = 4;
    int **matrix = create2DArray(rows, cols);
    
    if (matrix != NULL) {
        printf("2D array allocated successfully\n");
        // Example use (initialize to i*j)
        for (int i = 0; i < rows; i++)
            for (int j = 0; j < cols; j++)
                matrix[i][j] = i * j;
        
        // Free each row and then the array
        for (int i = 0; i < rows; i++) {
            free(matrix[i]);
        }
        free(matrix);
    }
    
    return 0;
}
Test your knowledge: C Allocate Memory
Quiz Configuration
4 of 8 questions
Sequential
Previous allowed
Review enabled
Early close allowed
Estimated time: 5 min
C MemoryTopic 58 of 64
←PreviousPrevNextNext→