Introduction to Programming Languages/Stack



Perhaps, the most common variables in a program are local variables, also known as automatic variables. In our example, variables `auto_var` and `auto_const` are local variables. These variables have local scope: they only exist inside of the function they declared and they lose their values as soon as the function returns. But, why so?

Every time a function is called something called activation record (or stack frame) is created. An activation record is the portion of the stack used to store a function's data upon its call. Thus, the activation record stores the function's parameters, local variables, return address, etc. The activation record of a function only exists while the function is running. After it finishes, its activation record is destroyed, thus destroying the function data. That is why local variables lose their value every time a function ends. (Remember: static variables do not behave this way. They are not stored in the stack, but in the data or bss section).

Stack Organization


As we showed on the picture before, the stack grows down, whereas the heap grows up. That means to say that if two objects are allocated on the stack, the address of the second object will be lower than the address of the first object.

Think of a postman delivering mail on a street. If he starts delivering people's mail from the end of the street towards its beginning, he would deliver first the mail of the people whose house number is higher. That's what happens with stack allocation: objects allocated first have higher addresses. The analogy is the same for heap allocation. The only difference is that the postman would start delivering mail from the beginning of the street and walk towards its end, thus delivering first the mail of people whose address is lower.

We give a little example below showing how it works. When we run the program below we see that the address of variable `aux_1` is greater than `aux_2`'s address, which is greater than `aux_3`'s address.

    #include <stdio.h>

    int sum(int a, int b) {
      int aux_1 = a;
      int aux_2 = b;
      int aux_3;
      printf("&aux_1 = %lu\n", &aux_1);
      printf("&aux_2 = %lu\n", &aux_2);
      printf("&aux_3 = %lu\n", &aux_3);
      aux_3 = aux_1 + aux_2;
      return aux_3;

    int main() {
      printf("Sum = %d\n", sum(2, 3));