[C] Dynamic Memory (Part 1.0): Stack v. Heap

Alright! After receiving positive responses to my proposal, I’m ready to start this [C] Dynamic Memory series.

Here are some suggested prerequisites:

  • Basic Understanding of Imperative Programming
  • Basic C Programming Knowledge
  • Confidence with Pointers
    • And what pointers represent

Whether or not you meet the above conditions to a tee, feel free to read the rest of this article (and the rest of the series).


The Stack

Each program, and each thread in a program, has a finite amount of memory to work with, allocated by the operating system, called the stack. If you attempt to use too much memory on the stack, you can trigger a stack overflow.

Other concerns aside, here are some instances in which the stack is used in C:

int main(void) {
    // ...
        int x;
        char* c;
        int arr[6] = {1,2,3,4,5,6};
    // ...
}

Variables, pointers (themselves, not what they point to), and static arrays are all stored on the stack.

Here are a few links for my skeptics:


The Heap

Aside from the stack, the heap (a.k.a. the free store) has more space but is often slower. I won’t go into too much detail about the exact difference, but know that the heap is where you would allocate large amounts of memory, especially if you only know how much memory you’re allocating at runtime.

If you know how much memory you need at compile-time, the stack may be preferential. There are always exceptions.

Nonetheless, using the heap in C, or any language, takes a little more effort on the programmer’s side.

int main(void) {
    // ...
        int *x;
        x = malloc( sizeof(int) );

        if (x == NULL)
            perror("Couldn't allocate for x");
    // ...
}

Above would be using the heap. Now time for a quick vocabulary session – sort of:

malloc is the function used to allocate a certain amount of memory on the heap. It takes one parameter: the number of bytes of memory to allocate.

To review, using malloc gets you some heap memory. But what should be done when the memory is no longer needed? Upon a program’s finishing, most modern operating systems will do away with any heap-allocated stuff still remaining. However, if we want to ensure peak code efficiency, we must learn to get rid of no longer needed memory by ourselves.

free does as you would expect. It frees up the memory pointed to by the parameter you pass it:

//...
free(x);
//...

Passing x (our pointer from the example before this one) to free clears out the memory to which it points. You can pass any kind of pointer to free. You do not need to pass unassigned pointers, which point to no memory, or pointers that point to another pointer’s memory to free.

You only free a block of memory once. Freeing the same memory multiple times causes problems, as you’ll find out throughout your journey with the C Programming Language.


Conclusion

All in all, malloc is how you obtain some memory; free is how you release that memory. malloc and free are like Yin and Yang: they should be balanced. Each call to malloc should be paired with one call to free. For a program to achieve inner peace, you could say, it needs to be balanced between memory allocations and memory releases.

That’s it for Stack v. Heap. Next time, we’ll be exploring how to make and use heap-allocated arrays with malloc and free.

Later…
@oaktree
that's all, folks!

11 Likes

I agree completely with your statement, and this is probably the most important part of your article, well … from my point of view ! Moreover, to ensure a better memory management and avoid memories leaking, I advise using valgrind, tool sensible to memory usage issues !

2 Likes

That will be covered in a tangential article, @Nitrax. By that, I mean valgrind. Man, I just don’t feel like tapping that Backspace key.

We’ll get there when I talk more about memory leaks. Baby steps, @Nitrax, baby steps…

2 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.