Compile time and runtime memory allocation

Data at the centric level is most crucial part of every program that you have written. All programs contain memory allocation, deallocation and data manipulation. In this article, I am going to discuss about memory allocation and different ways to allocate memory in C.

Memory allocation in C programming language

In programming each variable, constant occupies space in memory, defined by their data type. The compiler reserves required memory (bytes) during compilation according to the specified data type.

For example, there is a declaration statement int number; here, int is data type and number is variable (also referred as identifier). It tells the compiler to reserve 2 or 4 bytes (depending on compiler, 2 bytes for 16 bits compiler, 4 byte for 32 bits compiler) in memory. And the address of reserved memory bytes should be referred/identified by number.

Types of memory allocation in C

C programming or any other programming language basically support two types of memory allocation.

  1. Compile time memory allocation
  2. Runtime memory allocation

First thing that you should know that, here I am not talking about storage classes. Storage classes define location/area, lifetime, scope, default value etc. of bytes to allocate. I am writing about memory allocation time, whether it is allocated during the compilation process or runtime.

Compile time or static memory allocation

Compile time memory allocation means reserving memory for variables, constants during the compilation process. So you must exactly know how many bytes you require? Many text also refer compile time memory allocation as static or stack memory allocation.

Any variable, constant declared either at global scope (outside the main() function), static or as extern variable will occupy memory at compile time.

The biggest disadvantage of compile time memory allocation, we do not have control on allocated memory. You cannot increase, decrease or free memory, the compiler take care of memory management.

For example, if you need to declare a variable to store marks of N students, in that case N is undefined at compilation stage. Therefore you will end up with following declaration

int marks[100];

Above declaration will occupy memory for 100 students (reserved memory bytes will be 100 * sizeof(int)). Now, there are few issues with above declaration.

  1. Memory wastage: If you are providing input of 10 students, then 90 * sizeof(int) memory gets wasted and cannot be used for other purposes. It will be reserved until scope of marks variable, constants will be there.
  2. Less flexible: You cannot alter memory size once allocated. For an array of size 100, at any stage it is not possible again to input marks for 120 students.
  3. No control: You do not have any control on memory allocation and deallocation. You cannot clear allocated bytes from memory if you don’t require at any stage. The C compiler controls memory allocation and deallocation.

Example program to demonstrate compile time memory allocation

#include <stdio.h>

// Will occupy memory at compile time
// Global scope allocation
int a;

void foo()
{
    // Will occupy memory at compile time
    // static allocation
    static int c = 10;

    c++;

    printf("c = %d\n", c);
}


int main()
{
    // Will occupy the memory at compile time
    // Automatic allocation
    int b; 

    // assigning value to test/print
    a=10;
    b=20;

    // Print values
    printf("a = %d\n", a);
    printf("b = %d\n", b);

    foo();
    foo();

    return 0;
}

Output:

a = 10
b = 20
c = 11
c = 12

Runtime or dynamic memory allocation

Memory allocated at runtime either through malloc(), calloc() or realloc() is called as runtime memory allocation. You can also refer runtime memory allocation as dynamic or heap memory allocation.

Professional programmers prefer dynamic memory allocation more over static memory allocation. Since, we have full control over the allocated memory. Which means we can allocate, deallocate and can also reallocate memory when needed.

Example program to demonstrate runtime memory allocation

In this example, we will declare memory (at runtime) for N integer, take input from user and print the elements.

#include <stdio.h>
#include <stdlib.h>     // To use dynamic memory allocation functions


int main()
{
    // int pointer to store address of dynamic declared memory
    int *parr;

    // n - To get the limit
    // i - Loop counter
    int n, i;

    printf("Enter limit: ");
    scanf("%d", &n);

    // Allocate memory for n elements at runtime
    parr = malloc(n * sizeof(int));

    // check memory allocation error like overflow
    if (parr == NULL)
    {
        printf("Insufficient Memory!!!\n");
        return 0;
    }

    // Read n elements
    printf("Input %d elements:\n", n);
    for (i = 0; i < n; i++)
    {
        printf("Enter element %d: ", i + 1);
        scanf("%d", (parr + i));
    }

    // Print array elements
    printf("Input elements: ");
    for (i = 0; i < n; i++)
    {
        printf("%d ", *(parr + i));
    }

    // Release memory occupied by dynamically allocated array
    free(parr);

    return 0;
}

Output:

Input 5 elements:
Enter element 1: 1
Enter element 2: 2
Enter element 3: 3
Enter element 4: 4
Enter element 5: 5
Input elements: 1 2 3 4 5

Note: If you are declaring memory at runtime using dynamic memory allocation functions, please do not forget to release memory. In the above example I have used free(parr) function to release memory occupied by parr.

Compile time vs runtime memory allocation difference

Summing up the differences between compile time and runtime memory allocation in C programming language.

Compile time memory allocationRuntime memory allocation
Memory is allocated during program compilation.Memory is allocated during runtime.
You cannot reuse allocated memory.You can reuse allocated memory after releasing memory using free() function.
No library functions are required to allocate memory.Requires Library functions like malloc(), calloc(), realloc() to allocate memory at runtime.
We cannot modify size of allocated memory.We can modify size of allocated memory using realloc().

Drop your query, suggestion and feedback down below in comments section.

Happy coding 😉