Home StackOverFlow

Allocating memory

About
Many have heard of the term 'StackOverFlow' many are familiar with the StackOverFlow website.
This article explains trouble with memory allocation leading to stack overflow.
Although this article is dedicated to C programmers, most of it is relevant for other languages compiled to a binary executable.


Declaring on the Heap
When declaring variables not only the compiler needs to know their existence,
also the required space needs to be reserved somewhere in the available memory.
Initially when a program starts declaring variables outside of a function will reserve
them globally in a space called the heap.
The heap is either controlled by the Operating System, or in case of no OS (embedded hardware)
It has to be defined either by the programmer or uses some defaults set by the compiler.

Suppose we want to declare the following variables:
my_name Jeffrey
my_age 41
your_name Garry
your_age 35

Using a OS it does not really matter in what sequence you declare variable,
while in an embedded environment where memory is sparse you might want to optimize for minimum space usage.
We would declare the smallest units first, which would be characters and character arrays
Than slightly larger ones, that would be integers and finally floats.


We would declare something like:

Code snippet:
char my_name[8];
char your_name[6];
int my_age;
int your_age;

int main(int argc, char **argv)
{
    strcpy(my_name, "Jeffrey");
    strcpy(your_name, "Garry");
    my_age=41;
    your_age=35;

    printf("My name: %s, Your name %s\n", my_name, your_name);
    printf("My age : %2i, Your age %2i\n", my_age, your_age);
 }


Heap space when correctly declared

Code snippet:
Address      Variable   note
 17 0x00                decimal msb  0
 16 0x29     your_age   decimal lsb 35
 15 0x00                decimal msb  0
 14 0x33 !   my_age     decimal lsb 41
 13 0x00
 12 0x79 y
 11 0x72 r
 10 0x72 r
  9 0x61 a
  8 0x47 G
  7 0x00
  6 0x4a y
  5 0x65 e
  4 0x73 r
  3 0x66 f
  2 0x66 f
  1 0x65 e
  0 0x4A J 


Heap space when incorrect declared

Code snippet:
 Address     Variable   note
 16 0x00                decimal msb  0
 15 0x29     your_age   decimal lsb 35
 14 0x00                decimal msb  0
 13 0x33 !   my_age     decimal lsb 41
 12 0x79 y
 11 0x72 r
 10 0x72 r
  9 0x61 a
  8 0x47 G
  6 0x4a y
  5 0x65 e
  4 0x73 r
  3 0x66 f
  2 0x66 f
  1 0x65 e
  0 0x4A J 


Here we already see a problem coming up right away !
Notice how i reserved 8 characters for the name "Jeffrey" while it only contains 7 characters,
Same for Garry holding only 5 characters while i reserved 6 locations.
The reason for this is that strings are terminated by a 0 character, requiring an extra position.
If omitted (eg reserving 7 and 5 positions) the strcpy Jeffrey will overwrite the memory location for Garry unnoticed, later corrected by the strcpy function for Garry, destroying the null terminator for Jeffrey.
In this specific case that would be about it.
Garry's name also will be mangled, however on little or big endianess what would happen.
On big endian systems like a intel X86 alike processor, the null character will be replaced with the character 33 '!',
On little endian systems the Big part will be zero leaving the name seemingly undamaged.

Declaring on the Stack
A more confusing situation we will get when variables are declared on the stack
Keep in mind that the stack is filled from top to bottom, while arrays still count from bottom to top !

Same declaration on the stack

Code snippet:
void some_function(void)
{
    char my_name[8];
    char your_name[6];
    int my_age;
    int your_age;

    strcpy(my_name, "Jeffrey");
    strcpy(your_name, "Garry");
    my_age=33;
    your_age=28;

    printf("My name: %s, Your name %s\n", my_name, your_name);
    printf("My age : %2i, Your age %2i\n", my_age, your_age);
}


Stack area when correctly declared

Code snippet:
Address      Variable   note
 40 0x??     Function return address LSB
 39 0x00
 38 0x4a y 
 37 0x65 e
 36 0x73 r
 35 0x66 f
 34 0x66 f
 33 0x65 e
 32 0x4A J   my_name
 31 0x00
 30 0x79 y
 29 0x72 r
 28 0x72 r
 27 0x61 a
 26 0x47 G  your_name
 25 0x00                decimal msb  0
 24 0x33 !  my_age      decimal lsb 41
 23 0x00                decimal msb  0
 22 0x29    your_age    decimal lsb 35


Stack area when incorrect declared

Code snippet:
Address      Variable   note
 40 0x00     Function return address LSB damaged
 39 0x4a y 
 38 0x65 e
 37 0x73 r
 36 0x66 f
 35 0x66 f
 34 0x65 e
 33 0x4A J   my_name
 32 0x79 y
 31 0x72 r
 30 0x72 r
 29 0x61 a
 28 0x47 G  your_name
 27 0x00                decimal msb  0
 26 0x33 !  my_age      decimal lsb 41
 25 0x00                decimal msb  0
 24 0x29    your_age    decimal lsb 35



Notice here the return address to the caller on top of the stack
When Jeffreys name is written, the return address will be damaged leading to a program crash.
A stack overflow has occurred !

Declaring static
Declaring variables on the stack causes their reserved location to be lost when returning from a function.
Generaly this is no problem and actualy what we want..
After all leaving the function the their content is not relevant anymore.
There are however some cases where we want to keep local variables.
This can be in the odd and rather tricky case where we want to re-use a value for further usage like a integration process
or a interrupt handler (Although for both cases other safer solutions are posible).
Another reason can be performance.
Allocating and releasing variables use cpu power and sometimes depending on the secuence in which variables where assigned even hardly offer more efficient memory usage.

When declaring a variable being static, its location will bereserved on the heap, offering it a fixed memory location during the runtime of the program which is forever for embedded situations.



Injecting malicious code on the stack

More information
Some guy Guru99 gives his own opinion about the matter.

The difference between Heap and Stack

Using Pointers