The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science

Programming Languages and Tools:

CS:3210:0001

Lecture/Lab #19

Programming with C++

Arrays, array vs vector, smart pointers

Warm up

  • What will be the output of the following program?

int main() {
    int* n = new int( 17 );
    int* m = n;
    *m = 99;
    std::cout << "n: " << *n << std::endl;
    std::cout << "m: " << *m << std::endl;
    delete n;
    n = new int;
    *n = *m;
    std::cout << "n: " << *n << std::endl;
    std::cout << "m: " << *m << std::endl;
    delete m;
    delete n;
}
  • Member access through pointer:

car* c = new car;
(*c).start();
c->start();

Arrays, pointer arithmetic

int main() {
    int a[10] = { 5, -1, 0, 12, 
                  -7, 13, 99, 64, 
                  11, -22 };

    std::cout << a[0] << std::endl;
    std::cout << a[1] << std::endl;
    
    int* ptr = &a[0];
    ptr += 2;
    *ptr = 33;
    
    std::cout << a[2] << std::endl;
 }

a[6]

Stack

a[5]

a[4]

a[3]

a[2]

a[1]

a[0]

a[7]

a[8]

a[9]

0xffffffd0

0xfffffff8

0xfffffff4

0xfffffff0

0xffffffec

0xffffffe8

0xffffffe4

0xffffffd4

0xffffffdc

0xffffffd8

0xffffffe0

Array vs vector

int main() {
    std::vector<int> a = { 
                  5, -1, 0, 12, 
                  -7, 13, 99, 64, 
                  11, -22 };

    std::cout << a[0] << std::endl;
    std::cout << a[1] << std::endl;
 }

a[6]

Heap

 

a[5]

a[4]

a[3]

a[2]

a[1]

a[0]

a[7]

a[8]

a[9]

a (ptr=0xff000050, size=10)

Stack

0xff000050

Exercise 1

Finish implementation of a user-defined class `int_vector`

  • Open the exercise template

  • Write your code, press Run to test

  • When you're done, grab your Repl's link and send it as a direct message to me (agurtovoy)

  • Click on the corresponding option in the "Lab19 exercises" poll in #general

Problems with raw pointers

  • The pointer declaration (Thingy* ptr) doesn’t indicate whether it points to a single object or to an array.
  • It also doesn't say anything about whether we should destroy what it points to when we're done using it — i.e., if the pointer owns the thing it points to.
  • If we determine that we should destroy what the pointer points to, there’s no way to tell how.
  • Assuming we sorted out the above, it’s difficult to ensure that we perform the destruction exactly once along every path in our code.
  • There’s typically no way to tell if the pointer dangles, i.e., points to memory that no longer holds the object the pointer is supposed to point to. 

std::unique_ptr

Idiomatic replacement for

Exclusive ownership of heap allocated objects

widget* w = new widget();

// ...

delete w;
auto w = std::make_unique<widget>();

// ...
  • Zero overhead (unless you're using a stateful custom deleter)
  • Non-copyable but movable

 Primary characteristics: 

  • Can be stored in standard containers (e.g. std::vector)
  • Familiar dereference/member access syntax ( *w, w->memfun() ), no pointer arithmetics
Made with Slides.com