Stack vs Heap
Before understanding the differences between the Stack and Heap data structure, we should know about the stack and heap data structure separately.
What is Stack?
A Stack is a data structure that is used for organizing the data. Stack is similar to the stack a way organizing the objects in the real world. Some examples of stack of real world are stack of dinner plates, mathematical puzzle known as Tower of Hanoi containing three rods having multiple discs and stack of tennis balls. Stack is a collection with a property that an item or an object must be removed from one end known as the top of the stack.
It cannot be considered as the property rather it is considered as the constraint or restriction applied to the stack. In other words, we can say that only top of the stack is accessible and any item can be removed or inserted from the top of the stack. It follows LIFO (Last In First Out) principle in which recently added element must be removed from the stack first.
A stack is a list or a collection with a restriction that the insertion and deletion will take place from one end known as the top of the stack.
The following are the two operations available with a stack ADT:
Representation of stack
Stack is shown below:
We can observe in the above figure that stack looks like a container which is opened from one side. It can be represented logically as a three-sided figure as a container open from one side. The above representation is an empty stack and let's assume that stack is 's'. It is a stack of integers. Now we will perform push and pop operations on the stack. Suppose we want to insert 2 element in the stack. After push operation, the stack would look like:
Since there is only one element in the stack, so 2 element would be at the top of the stack. If we want to insert 1 element in the stack, then the stack would like:
Since element 1 comes above the element 2, so element 1 would be considered the top of the stack. If we perform pop operation, then the topmost element, i.e., 1 would be removed from the stack as shown below:
What is Heap?
Heap is also a data structure or memory used to store the global variables. By default, all the global variables are stored in the heap memory. It allows dynamic memory allocation. The heap memory is not managed by CPU. Heap data structure can be implemented either using arrays or trees.
It is a complete binary tree that satisfies the condition of the heap property where complete binary tree is a tree in which all the levels are completely filled except the last level. In the last level, all the nodes are far as left as possible.
Pointers and Dynamic memory
Here, we will see the architecture of memory. It is very crucial to know that how system manages the memory and accessible to us as programmers. The memory which is assigned to the program or application in a typical architecture is divided into four segments. One segment of the memory stores the instructions which are to be executed. Another segment of the memory stores the global or the static variables. The global variables are the variables which are declared outside the function and the lifetime is throughout the program. The third segment, i.e., stack is used to store all the function calls and the local variables. When any function is called then it occupies some space in the memory known as a stack memory.
Let's understand the stack memory through an example.
In the above code, execution starts from the main() method. So main() method would be given a memory in the stack as shown below:
When the sum() method is called, the control moves to the sum() function.
The sum() method calls the square() method; therefore, the square method would be given a memory in the stack as shown below:
Once the square() method return statement is executed, the control moves back to the sum() method and the square() method gets removed from the stack as shown below:
When the return statement of the sum() method is executed, the control moves to the main() method and sum() method gets removed from the stack as shown below:
In the main() method, printf() function is called so it gets memory in the stack as shown below:
Once the execution of printf() statement is completed, the printf() and main() methods are removed from the stack memory as shown below:
There are some limitations of using a stack memory. Suppose operating system reserves 1MB stack memory for the program. If program keeps calling the functions again then stack memory would not be sufficient and it leads to the stack overflow condition. The stack overflow causes a program to crash. So, we can say that the stack memory does not grow runtime.
Another limitation of stack is that the scope of the variable cannot be manipulated. The allocation and deallocation of memory onto the stack are set by the rule, i.e., when the function is called then it is pushed onto the top of the stack and when pop() operation is called then the element is removed from the top of the stack.
The third limitation of the stack is that if we define the large data type such as array and the size of the array is not defined at the compile time. We want to define the size of the array based on some parameters, and defining the size of the array at the runtime is not possible with the stack.
So, to allocate the large chunks of memory and keep the memory aside till the time we want, we can use a heap data structure. Unlike stack data structure, the size of the heap memory can vary and it is not fixed throughout the lifetime of the application. In heap memory, there is no set rule for the allocation and deallocation of memory. A programmer can itself manually handle the memory. The abstracted way for the programmer of looking at the heap as a large free of memory available to use and we can use it as per our needs.
Heap is also known as a dynamic memory and using heap, can be considered as the dynamic memory allocation. To use dynamic memory, we need to use some functions. In C language, we can use malloc() and calloc() to allocate the memory and free() function to deallocate the memory, whereas, in C++ language, we use new operator for the allocation and delete operator for the deallocation.
Let's understand the dynamic memory through an example.
Explanation of the above code.
First, we declared the 'a' variable and it gets allocated within the stack frame of the main() method in the stack as shown below:
To allocate something in the heap memory, we need to use the malloc() function. We have used the malloc() function in the above code in which we pass the sizeof(int) defines that 4bytes of block is allocated in the heap memory. This function returns the void pointer that contains the starting address of the block. The 'p' is a pointer variable local to the function so it gets stored in the stack as shown below:
Again, we have allocated new block of memory pointed by the 'p' variable, so 'p' does not hold the address of the previous block. The block having value 11 is an unnecessary consumption of memory. In heap, the memory is not automatically deallocated, we have to release the memory manually. So, in the above code, we have used the free(p) function in which we pass the 'p' to deallocate the memory pointed by 'p'.
Differences between Stack and Heap