CMPT 225–Call Stack & Heap Memory

The call stack

...ABC... ... \leftrightarrow A \leftrightarrow B \leftrightarrow C \leftrightarrow ...

Call Stack Illustration

Code is in call_stack.cpp

Call stack for this process:

Name Data
main a=1, b=0
f(2) c=2, d=3, e=8
g(4) i=4
g <code for g>
f <code for f>
main <code for main>

Stack Code

Picture of code, which can be found in stack_pointers.cpp

Picture of code output, which can be found in stack_pointers_output.txt

Dynamic Memory or Heap

In C++:

Ex: Basic Types on Call Stack & Heap

Code snippet below:

f(){
  int n; //n is on stack
  n=6;
  int * np;//np is on stack
  np = new int;// new int is stored in heap
  *np = 7; // np points to the location.
}

Ex: Basic Types on Call Stack & Heap

See code above.

Call stack:

Name Value Note
n 6  
np pointer np is a pointer to the location on the heap.

Heap:

Value
...
7
...

Note: When f ends, np is gone (the stack is popped), but the space it pointed to is not.

Class Instances on Heap & Stack (combines notes on two slides)

Code snippet:

List * f(){
  List L;
  List * Lp;
  Lp = new List();
  return Lp; // returns pointer
}

main(){
  ...
  List * lst = f(); // lst becomes a pointer to the list object
  ...
}

Call Stack:

Name Values Notes
lst pointer to heap in main
L <List Object> entire List object; in function f (destroyed when f ends)
Lp pointer to <List Object> in function f (this pointer is also destroyed when f exits); annotation: this instanciates the list class

Heap:

Value Notes
<List Object> entire list object

Accessing Instance Members in C++ (combination of notes in two slides)

Suppose a class Store with:

Consider this code fragment:

f(){
  ...
  Store s1;
  s1.put(5);
  y=s1.get();//y=5
  ...
  Store *s2;
  s2=new Store();// (annotation: XX)
  s2.put(5);// (annotation: X)
  y=s2.get()// (annotation: X)
  ...
  *s2.put(5);// (annotation: X)
  y=*s2.get();// (annotation: X)
  ...
  (*s2).put(5);// (annotation: check mark)
  y=(*s2).get();// (annotation: check mark)
  ...
  s2->put(5); // equiv. to (*s).put(5)// (annotation: check mark)
  y=s2->get(); // equiv. to y=(*s).get()// (annotation: check mark)
}

Call Stack:

Name Value Notes
s2 pointer to <Store Object>  
s1 <Store Object [x=5]>  

Heap:

Value Notes
<Store Object [x=5]>  

Using the Textbook List Class

See textbook_list.cpp and List.h.

Call stack during the run of the program:

Name Value Notes
N 5 within main
lst <List Object [size=5, head=0, tail=4]> within main

The heap is empty.

See “doubly linked list” example in lecture 05.

The List Class

Two images of the doubly linked list slides from lecture 05 with a big red X written overtop each image.

The List Class - Constructor

Code snippet:

private:
  int theSize;
  Node *head;
  Node *tail;
  void init()
  {
    theSize = 0;
    head = new Node;
    tail = new Node;
    head->next = tail;
    tail->prev = head;
  }
};

After constructor:

Name Next Value Prev
head pointer nullptr nullptr
tail nullptr nullptr pointer

Code snippet form List.h:

Node(const Object& d = Object{}, Node* p = nullptr, Node* n = nullptr)
  : data{d}, prev{p}, next{n} {}

The List Class - The iterators

The List Class - the push_back function

// add an element to the tail end of the list
// end() is the end iterator
// x is the element to add
void push_back(const Object& x){insert(end(), x);}

iterator insert(iterator itr, const Object& x){
  Node *p = itr.current; // turns the iterator into a pointer
  ++theSize; //increments size variable
  return iterator(p->prev=p->prev->next=new Node(x, p->prev, p)) // turns the pointer into an iterator
  // p->prev=p->prev->next=new Node(x, p->prev, p)) does two things:
  // 1. Makes a new node `N`
  // 2. stores a pointer to `N` in p->prev and it p->prev->next
}

The List Class - Inserting the first element (combination of notes from two slides)

Code snippet:

// itr is the end
iterator insert(iterator itr, const Object& x){
  Node *p = itr.current;// itr.current is the tail
  ++theSize;
  return iterator(p->prev=p->prev->next=new Node(x, p->prev, p)); // turns pointer into iterator
  // x is new list element
  // p->prev is initial value of prev
  // p is initial value of next
}

List pointed to by pointer p (original)

Name Next Value Prev
head pointer nullptr nullptr
tail nullptr nullptr pointer

The “new Node(…)” object:

Next Value Prev
pointer nullptr pointer

Transcriber’s addition (implied in diagram): What does p->prev=p->prev->next=New Node(...) do to this list?

Transciber’s note: It inserts the new Node(...) into the list like so:

Name Next Value Prev
head pointer nullptr nullptr
new Node(...) pointer nullptr pointer
tail nullptr nullptr pointer

Transciber’s note: This cancels the previous connection between head and tail directly.

Using the Textbook List Class

Code snippet:

#include "dsexceptions.h"
#include "List.h"
int main(){
  const int N = 5;
  List<int> = lst;
  for(int i=N-1; i<0; --i){
    lst.push_front(i);
  }
  return 0;
}

When lst contains the two values [1, 2]:

Call Stack:

Name Value Notes
N 5  
lst <List Object [theSize=2, head=pointer, tail=pointer>  

Heap (transcriber’s note: the link takes you to the value, but the pointer is to the group of values [next, value, prev), A.K.A. a Node):

Value Notes
Node.next Node index 0
Node Value: 1 Node index 0
Node.prev Node index 0
Node.next (nullptr) Ending Node
Node Value: ? Ending Node
Node.prev Ending Node
Node.next Node index 1
Node Value: 2 Node index 1
Node.prev Node index 1
Node.next Beginning Node
Node Value: ? Beginning Node
Node.prev (nullptr) Beginning Node

Linked List Ends

Transcriber’s note: tell me if you like this way of transcribing simplified linked lists where the individual values don’t matter, but only a linear relationship between the nodes:

For [4, 5, 6]:

headbeginning node456ending nodetail \text{head} \leftrightarrow \text{beginning node} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}

versus

head456tail \text{head} \leftrightarrow 4 \leftrightarrow 5 \leftrightarrow 6 \leftrightarrow \text{tail}

For [5]:

headbeginning node5ending nodetail \text{head} \leftrightarrow \text{beginning node} \leftrightarrow 5 \leftrightarrow \text{ending node} \leftrightarrow \text{tail}

versus

head5tail\text{head} \leftrightarrow 5 \leftrightarrow \text{tail}

For []:

headbeginning nodeending nodetail\text{head} \leftrightarrow \text{beginning node} \leftrightarrow \text{ending node} \leftrightarrow \text{tail}

versus (transcriber’s note: the lack of connection is intentional)

head,tail\text{head} , \text{tail}

End

After the “End” slide, some previous slides are repeated for no apparent reason.