Last week, in our article about “How Not to Code”, we mentioned in passing concepts of the frame, also called the stack, and the heap. I’m not sure if the stack and the heap are supposed to be philosophies of office organization or if they are characters in a bad mob movie from the 1970’s, but in programming, they are key to how your computer works internally.
In computer science, a “stack” is a structure where the last element added is the first element removed. Sometimes, this is how life in general goes.
Suppose you are performing a routine task at work. Then a coworker sends you an email asking for help. Then your supervisor comes in with something for you to do and you start working on that task. Lastly, a customer calls and you start to help them. We could represent this series of interruptions as a stack.
In a stack, in order to remove an item lower on the stack, you have to first remove the items above it. Your computer executes programs the same way. When one function calls another, the called function is added to the top of the stack and earlier functions will not continue until later ones are completed.
Memory is also allocated to functions using a stack. (We also call this allocating memory on the “frame”.) Consider these two functions in C++:
double dblPi = 3.14159;
int intRadius = intDiameter / 2;
return dblPi * intRadius;
int intCircumference = 0;
sprintf(szMessage, “The circle is approximately %d inches around”, (int)PerformCalculation(5));
MessageBox(NULL, szMessage, “Circle”, MB_OK);
It is known at compile time that ShowMessage() will need 104 bytes of memory for the two variables it declares (assuming integers are four bytes) and PerformCalculation will need 12 bytes of memory for its variables. (Actually, some amount of memory is also allocated for the “anonymous variables”, or, in other words, the intermediate calculations, such as the return value of PerformCalculation().)
Allocating memory on the stack is very efficient – when a program runs, it allocates some amount of “stack space” and when a new function is entered, all the program has to do is move “push” that function’s variables onto the stack and “pop” them off when it is done.
Alternatively, memory can be allocated using the “heap”. Consider this alternate version of PerformCalculation, which uses the word “new” to declare its variables:
double *pdblPi = new double;
*pdblPi = 3.14159;
int *pintRadius = new int;
*pintRadius = intDiameter / 2;
int intReturn = *pdblPi * *pintRadius;
When the word “new” is used, the program asks the operating system for a block of memory that it can use to store the variable. In this function, pintRadius does not actually contain the radius itself, but, rather, it contains a memory address where the radius can be found. Because this memory is allocated dynamically and potentially requires the operating system to hunt for a free block of memory, or even to use the swap file, this code will execute more slowly.
So, when programming, it is obviously preferable to declare variables on the stack instead of on the heap, where possible.
One of the downsides in C# relative to C++ is that it is completely impossible to declare an object (a class) on the frame. In C++, this is valid syntax:
This code creates an instance of the CDialog class on the stack. In C#, though, classes can only be allocated on the heap. This makes it less possible to write efficient code.
What language do you like better – C++ or C#? Let us know in your comments.
image credit: Zzubnik