Memory Allocation in C: Static and Dynamic Memory
Learn how memory is allocated in C programming. Discover the differences between static memory (compile-time memory allocation) and dynamic memory (run-time memory allocation), and understand when and how to use them in your C programs.
C Allocate Memory
How Memory is Allocated
When you reserve memory for your variables, that's called memory allocation. The way memory is allocated depends on the type of memory you're working with. In C, there are two main types: static memory and dynamic memory.
Static Memory
Static memory is reserved for variables before your program even starts running, which is why it's also called compile-time memory allocation. This type of memory is automatically allocated when your program is compiled.
For example, if you create an array of integers to hold data for 15 students in a semester, C will reserve enough memory to store 15 elements. If an integer takes up 4 bytes, that means 60 bytes will be set aside:
Syntax
int students[15];
printf("%lu", sizeof(students)); // 60 bytes
Output
60 bytes
But if only 10 students show up, you’ve now wasted memory on 5 extra spaces that aren’t being used. Since you can’t change the size of the array once it’s set, that reserved memory stays unused.
While the program will still run, it might not be as efficient as it could be if you have a lot of similar cases.
Dynamic Memory
Dynamic memory is more flexible because it gets allocated while the program is running, which is why it's called runtime memory allocation. Unlike static memory, you can control exactly how much memory is needed and allocate it as the program runs.
This type of memory isn’t tied to a specific variable. Instead, you access it through pointers. To allocate dynamic memory, you use functions like malloc()
and calloc()
from the stdlib.h
header file.
Syntax
int *ptr1 = malloc(size);
int *ptr2 = calloc(amount, size);
The malloc()
function takes one parameter: size
, which tells it how many bytes to allocate. calloc()
takes two parameters: amount
(how many items you need) and size
(how big each item is in bytes).
Best Practice: Use sizeof
for Memory
It’s a good idea to use the sizeof
operator to figure out how much memory you’ll need for a data type:
Syntax
int *ptr1, *ptr2;
ptr1 = malloc(sizeof(*ptr1));
ptr2 = calloc(1, sizeof(*ptr2));
Make sure you use *ptr1
with sizeof
. If you forget the *
and write sizeof(ptr1)
, you’ll only get the size of the pointer itself (usually 8 bytes), not the memory you actually want to allocate.
Example: Dynamic Memory for Students
Let’s fix our earlier example of allocating memory for 15 students and instead dynamically allocate memory for the actual 12 students who attend:
Syntax
int *students;
int numStudents = 12;
students = calloc(numStudents, sizeof(*students));
printf("%d", numStudents * sizeof(*students)); // 48 bytes
Output
48 bytes
Now, we’ve only reserved memory for 12 students, so nothing is wasted.
Stack Memory
In addition to static and dynamic memory, there’s another type called stack memory. This is a special kind of dynamic memory that’s used when functions are called. The variables inside a function use stack memory, and it’s automatically freed when the function finishes running.
Stack memory is important to keep in mind, especially when dealing with nested function calls or recursion, as overuse can lead to stack overflow errors.