CS 70

The Heap and new

The Heap

  • Duck speaking

    You said ”it would be great it we only had to allocate and initialize an Elephant when we actually need one”, but how can we allocate an Elephant when we need it? I thought we had to allocate everything when the function starts.

  • LHS Cow speaking

    Good point! It's true that everything in the stack frame is allocated when the function starts.

  • RHS Cow speaking

    But, we're not going to put our Elephants on the stack!

In addition to the stack, there is another region of memory called the heap.

The stack, as we know, stores the values of local variables in each function call. Stack memory is allocated when a function is called and deallocated when that function returns.

But heap memory is allocated and deallocated whenever we tell it to be! So memory can be allocated while a function is executing and it can then persist even after a function returns.

  • LHS Cow speaking

    Note that stacks are a kind of data structure, and “the stack” used by our program is actually organized as a stack—calling a function pushes a new stack frame onto the stack, and returning pops the most recent stack frame off the stack.

  • RHS Cow speaking

    There's also a data structure called a heap (you may or may not have heard of it), but “the heap” used by our program is not organized like that data structure.

  • LHS Cow speaking

    Here “heap” just refers to the fact that we have a disorganized pile of stuff

The new Keyword

The line

int* p = new int{42};

allocates and initializes a single integer on the heap with the value 42.

  • RHS Cow speaking

    Let's walk through what happens in this little snippet!

Key idea: The new keyword

  • Allocates space on the heap for the given type
  • Initializes the data as specified
  • Returns a pointer to the new piece of data

We have terms to distinguish different ways of allocating memory:

  • Static allocation: memory that is allocated for the entire duration of the program (e.g., a static data member in a class—there isn't a separate one for each object of that class, there is exactly one for the entire program)
  • Automatic allocation: memory allocated on the stack (because it is allocated/deallocated automatically when functions begin/end)
  • Dynamic allocation: memory allocated on the heap (because the allocation is "dynamically" determined at runtime as opposed to compile time)

The new keyword is used for dynamic allocation.

Elephants on Demand

  • Cat speaking

    Oh, I see. If our array contains pointers to Elephants, then we can point them to a new Elephant whenever it's time to make one.

  • LHS Cow speaking

    Yup, that's where we are heading.

Say we have an array of pointers,

Elephant* elephants[5];

And now, imagine that we want to create the first Elephant with the name “Peanut” and the age set to 2.

Give a line of code that sets the pointer at elephants[0] to point to a new Elephant object with the given name and age.

Answer:

elephants[0] = new Elephant{"Peanut", 2};

Here's a tricky one: Give a line of code that calls getName() on the Elephant that elephants[0] points to and then prints the result.

One possible answer is

cout << elephants[0]->getName() << endl;

Some other correct answers using less-preferred syntax are

cout << (*elephants[0]).getName() << endl;
cout << (*elephants)->getName() << endl;
cout << (**elephants).getName() << endl;
  • LHS Cow speaking

    Let's go through those answers real quick to make sure they make sense.

(When logged in, completion status appears here.)