Memory Diagram

​Stack Frames and Function Calls

  1. Function Called (including main)

  2. New area of memory (stack frame) is set up on top of the stack.

    • Stack frame has an entry for

    • each formal parameter

    • return address – where in the code to return to after function exits

    • frame pointer – location of previous frame

    • each local variable

  3. Body of function executes

  4. Function finishes and its stack frame goes away

    • i.e. memory is recycled for later use

Stack Frame

Contains

  • Parameters

    • Value of actual arguments are copied into corresponding formal arguments (parameters) in stack frame

    • In the same order as the parameters: 1st argument to 1st parameter, 2nd to 2nd, etc.

    • The function computes using the formal arguments (parameters)

    • No change is made to the actual arguments

  • Local variables

  • Information for returning to the calling function

    • Return address: address in code of calling function to go back to

    • Frame pointer: location of previous frame

Memory Diagram

  • Helps us visualize the call stack

  • zyBooks starts at top since addressing is considered to start at zero and diagrams are frequently drawn with zero at the bottom.

    • This is the standard convention: The stack grows down. Low addresses are down, high addresses are up.

  • However, when talking about stacking, we usually think: put things on top!

    • So we will start at the bottom (high addresses) so that when we put a stack frame on top (lower address), it looks like it is going on top: The stack grows up.

    • Either way: the stack grows from high addresses -> low addresses

  • When we draw a memory diagram, we’ll include information about

    • Parameters

    • Local variables

    • Name of function

Program

int em(int a, int b) {
    int k = 1000;
    int whoop = a + b + k;
    return whoop;
}
int gig(int rev) {
    int howdy = 22;
    return em(rev, howdy);
}
int main() {
    int b = gig(em(7, -10));
    cout << "b: " << b << endl;
    return 0;
}
memory diagram for the program above
  • How do pointers and references affect the memory diagram?

  • Pointers store an address.

    • Rather than worry about a particular number:

    • Use a small circle to indicate the value is an address.

    • Use an arrow from the circle that points to the location/address.

  • References are similar to pointers

    • Some refer to them as “safe pointers”

    • Technically, references are an alias to a memory location

    • We’ll draw it like a pointer, even though it’s technically not

int mi(int j) {
    int i = 5;
    return j % i;
}
int re(int& s, int p) {
    s = 12;
    return mi(s*p);
}
int doe(int w) {
    int k = 2;
    int q = w+3;
    cout << "k: " << k << endl;
    int z = re(k, q);
    cout << "k: " << k << endl;
    return z + w;
}
int main() {
    int b = doe(11);
    cout << "b: " << b << endl;
}
memory diagram for the program above

How are arrays represented in the memory diagram?

  • “An array is just a pointer”

    • Not the whole story…

  • The space allocated for an array goes on the stack or the heap

    • Stack: working memory for functions

    • Heap: free store, dynamically allocated memory

  • An array on the heap is stored as a pointer on the stack to a contiguous block of memory on the heap

  • An array on the stack is stored as a contiguous block of memory on the stack

    • No need to store the address

unsigned int strlen(const char* arr) {
    unsigned int len = 0;
    while (*arr) {
        len++
        arr++;
    }
    return len;
}
int main() {
    char A[] = “hello world”;
    strlen(A);
    return 0;
}
memory diagram for the program above
memory diagram for the program above

How are structs represented in the memory diagram?

  • Structs are bundles of data

    • Can also have functions… struct + functions = class

  • Data in a struct is stored in contiguous memory

    • Space is allocated for each field (member variable / attribute) of the struct

typedef struct Date {
    short day;
    short month;
    short year;
} Date;

A memory diagram with a struct on the stack

short dow(const Date date) {
    short d = date.day;
    short m = date.month;
    short y = date.year;
    y -= m<3;
    return (y+y/4-y/100+y/400+"-bed=pen+mad."[m]+d)%7;
}
int main() {
    Date date = {17, 9, 2019};
    cout << dow(date) << endl;
    return 0;
}
memory diagram for the program above

Last updated

Was this helpful?