Memory: Stack Vs Heap

Share Your Love

A stack is a section of memory in a computer that keeps temporary variables generated by a function. Variables are declared, stored, and initialised in the stack during runtime.

It’s a type of temporary storage memory. The memory of the variable will be automatically wiped once the computational process is completed. Methods, local variables, and reference variables are generally found in the stack section.

We’ve seen how to declare fundamental type variables like int, double, and so on, as well as complex types like arrays and structs. The way we’ve been declaring them so far, using a syntax similar to that of other programming languages like MATLAB and Python, puts these variables on the stack in C/C++.

In this tutorial, you will learn,

The Stack:

The question is “What’s the status of the stack?” It’s a unique part of your computer’s memory where each function (including the main() function) saves temporary variables. The stack is a “LIFO” (last in, first out) data structure that the CPU closely manages and optimizes.

A new variable is “pushed” onto the stack every time a function declares one. Then, whenever a function finishes, all of the variables it pushed into the stack are freed (that is to say, they are deleted). When a stack variable is freed, the memory space it previously occupied becomes available to other stack variables.

The benefit of storing variables on the stack is that memory is managed for you. You don’t have to manually allocate memory or release it after you’re done with it. Furthermore, because the CPU organizes stack memory so well, reading and writing to stack variables is lightning fast.

A key to understanding the stack is the notion that when a function exits, all of its variables are popped off of the stack (and hence lost forever). Thus stack variables are local in nature. This is related to a concept we saw earlier known as variable scope, or local vs global variables. A common bug in C programming is attempting to access a variable that was created on the stack inside some function, from a place in your program outside of that function (i.e. after that function has exited).

Another element of the stack to remember is that the size of variables that can be stored on the stack has a limit (which varies by OS). This is not the case for heap-allocated variables.

To sum up the stack,

  • As functions push and pop local variables, the stack expands and shrinks.
  • There’s no need to worry about memory management because variables are automatically allocated and removed.
  • There are size restrictions on the stack.
  • The stack variables exist only as long as the function that produced them is active.

The Heap:

The heap is a part of your computer’s memory that isn’t managed by the CPU and isn’t managed automatically for you. It’s a more free-floating memory region (and is larger). You must use malloc() or calloc(), which are built-in C methods, to allocate memory on the heap. You are responsible for executing free() to deallocate memory allocated on the heap once you no longer require it. If you don’t do this, you’ll end up with a memory leak in your program. 

That is, memory on the heap will still be set aside (and won’t be available to other processes). As we will see in the debugging section, there is a tool called valgrind that can help you detect memory leaks.

Unlike the stack, the heap does not have size restrictions on variable size (apart from the obvious physical limitations of your computer). Heap memory is slightly slower to be read from and written to because one has to use pointers to access memory on the heap. We will talk about pointers shortly.

Unlike the stack, variables created on the heap are accessible by any function, anywhere in your program. Heap variables are essentially global in scope.

Stack vs Heap Pros and Cons:

Stack:

  • very fast access
  • don’t have to explicitly de-allocate variables
  • space is managed efficiently by CPU, memory will not become fragmented
  • local variables only
  • limit on stack size (OS-dependent)
  • variables cannot be resized

Heap:

  • variables can be accessed globally
  • no limit on memory size
  • (relatively) slower access
  • no guaranteed efficient use of space, memory may become fragmented over time as blocks of memory are allocated, then freed
  • you must manage memory (you’re in charge of allocating and freeing variables)
  • variables can be resized using realloc()

Examples Of Stack And Heap:

Here is a short program that creates its variables on the stack. It looks like the other programs we have seen so far.

#include <stdio.h>
double multiplyByTwo (double input) {
  double twice = input * 2.0;
  return twice;
}
int main (int argc, char *argv[])
{
  int age = 30;
  double salary = 12345.67;
  double myList[3] = {1.2, 2.3, 3.4};
  printf("double your salary is %.3f\n", multiplyByTwo(salary));
  return 0;
}
double your salary is 24691.340

On lines 10, 11 and 12 we declare variables: an int, a double, and an array of three doubles. These three variables are pushed onto the stack as soon as the main() function allocates them. When the main() function exits (and the program stops) these variables are popped off of the stack. Similarly, in the function multiplyByTwo(), the twice variable, which is a double, is pushed onto the stack as soon as the multiplyByTwo() function allocates it. As soon as the multiplyByTwo() function exits, the twice variable is popped off of the stack and is gone forever.

As a side note, there is a way to tell C to keep a stack variable around, even after its creator function exits, and that is to use the static keyword when declaring the variable. A variable declared with the static keyword thus becomes something like a global variable, but one that is only visible inside the function that created it. It’s a strange construction, one that you probably won’t need except under very specific circumstances.

Here is another version of this program that allocates all of its variables on the heap instead of the stack:

#include <stdio.h>
#include <stdlib.h>
double *multiplyByTwo (double *input) {
  double *twice = malloc(sizeof(double));
  *twice = *input * 2.0;
  return twice;
}
int main (int argc, char *argv[])
{
  int *age = malloc(sizeof(int));
  *age = 30;
  double *salary = malloc(sizeof(double));
  *salary = 12345.67;
  double *myList = malloc(3 * sizeof(double));
  myList[0] = 1.2;
  myList[1] = 2.3;
  myList[2] = 3.4;
  double *twiceSalary = multiplyByTwo(salary);
  printf("double your salary is %.3f\n", *twiceSalary);
  free(age);
  free(salary);
  free(myList);
  free(twiceSalary);
  return 0;
}

As you can see, using malloc() to allocate memory on the heap and then using free() to deallocate it is no big deal, but is a bit cumbersome. The other thing to notice is that there are a bunch of star symbols * all over the place now. What are those? The answer is, they are pointers. The malloc() (and calloc() and free()) functions to deal with pointers, not actual values. We will talk more about pointers shortly. The bottom line though: pointers are a special data type in C that stores addresses in memory instead of storing actual values. Thus on line 5 above, the twice variable is not a double, but is a pointer to a double. It’s an address in memory where the double is stored.

When to use the Heap?

When should the heap be used and when should the stack be used? If you need to allocate a huge block of memory (such as a large array or a large struct) and maintain that variable around for a long period (such as a global), you should do it on the heap. If you’re working with little variables that only need to persist as long as the function that uses them is alive, the stack is the way to go; it’s easier and faster.

If you need variables like arrays and structs that can change size dynamically (e.g. arrays that can grow or shrink as needed) then you will likely need to allocate them on the heap, and use dynamic memory allocation functions like malloc()calloc()realloc() and free() to manage that memory “by hand”. We will talk about dynamically allocated data structures after we talk about pointers.

Accordingly C/C++ The Stack And Heap:

The Stack:

  • Stored in computer RAM just like the heap.
  • Variables created on the stack will go out of scope and are automatically deallocated.
  • Much faster to allocate in comparison to variables on the heap.
  • Implemented with an actual stack data structure.
  • Stores local data, return addresses, used for parameter passing.
  • Can have a stack overflow when too much of the stack is used (mostly from infinite or too deep recursion, very large allocations).
  • Data created on the stack can be used without pointers.
  • You would use the stack if you know exactly how much data you need to allocate before compile time and it is not too big.
  • Usually has a maximum size already determined when your program starts.

The Heap:

  • Stored in computer RAM just like the stack.
  • In C++, variables on the heap must be destroyed manually and never fall out of scope. The data is freed with deletedelete[], or free.
  • Slower to allocate in comparison to variables on the stack.
  • Used on demand to allocate a block of data for use by the program.
  • Can have fragmentation when there are a lot of allocations and deallocations.
  • In C++ or C, data created on the heap will be pointed to by pointers and allocated with new or malloc respectively.
  • Can have allocation failures if too big of a buffer is requested to be allocated.
  • You would use the heap if you don’t know exactly how much data you will need at run time or if you need to allocate a lot of data.
  • Responsible for memory leaks.
i6k0Z
Image source: vikashazrati.wordpress.com

Read More:

https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

Source: Stackoverflow.com

Share Your Love
Avatar photo
Lingaraj Senapati

Hey There! I am Lingaraj Senapati, the Founder of lingarajtechhub.com My skills are Freelance, Web Developer & Designer, Corporate Trainer, Digital Marketer & Youtuber.

Articles: 411

Newsletter Updates

Enter your email address below to subscribe to our newsletter