Dynamic Memory

Memory Layout

Stack

  • As stack grows / shrinks, items are automatically cleared from Memory

    • i.e. when a function ends, all of its objects (variables) are cleared from Memory

  • Sometimes we want objects to live on after a function is finished.

    • Put on the Heap / Free Store

How to use the heap?

  • Use ‘new’

    • Gets memory from the heap

    • Returns a pointer

  • Use ‘*’ to dereference the pointer

  • Initialize with nullptr (i.e. 0) nullptr

int i = 7; // put item on the stack
int* j = nullptr;
j = new int(11); // put item on the heap
cout << “Value in i: " << i << endl;
cout << "Address of i: " << &i << endl;
cout << “Value in j: " << j << endl;
cout << "Address of j: " << &j << endl;
cout << "*j (value at address pointed to in j): " << *j << endl;
int* k = new int[5]; // allocate an array on the heap

Heap

  • If we put something on the heap we also have to remove it.

    • If we don’t we might have a memory leak.

    • More on memory management / challenges with pointers later.

  • How to remove from the heap?

    • Use ‘delete’

    • Use ‘delete[]’ if deleting an array

delete j; // remove item from the heap
// j still points to the memory in the heap
// that can be a problem

Only use delete with dynamic memory!!!

Notes on new / delete

  • If you delete memory that has already been deleted, then an exception will likely occur.

  • If you delete a pointer that is set to nullptr, then no error occurs. (The delete operator is designed to have no effect when used on a null pointer.)

  • If you try to dereference a pointer that has been deleted, then an exception will likely occur.

  • So try to set the pointer to nullptr after you use delete.

RAII

  • Resource Acquisition Is Initialization (RAII)

    • Try to allocate resources in constructor (i.e. allocate memory from the heap)

    • Try to deallocate resources in destructor (i.e. deallocate memory from the heap)

Pointers to Structures

  • A structure variable has an address

  • Pointers to structures are variables that can hold the address of a structure:

    • Student *stuPtr;

  • Can use & operator to assign address:

    • stuPtr = & stu1;

  • Structure pointer can be a function parameter

Accessing Structure Members via Pointer Variables

  • Must use () to dereference pointer variable, not field within structure:

    • cout << (*stuPtr).studentID;

  • Can use structure pointer operator to eliminate () and use clearer notation:

    • cout << stuPtr->studentID;

Pointers to Classes

The -> operator

Color* c = new Color { 123,233,18 };
cout << "red: " << c->get_red() << endl;
cout << "green: " << c->get_green() << endl;
  • -> is equivalent to dereferencing and then using the dot operator

  • Alternatively we could do the following

    • However, this is not normally done.

Color* c = new Color { 123,233,18 };
cout << "red: " << (*c).get_red() << endl;
cout << "green: " << (*c).get_green() << endl;

Last updated

Was this helpful?