Memory Diagram
Stack Frames and Function Calls
Function Called (including main)
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
Body of function executes
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;
}

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;
}

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;
}


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;
}

Last updated
Was this helpful?