CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17:...

27
CSCE 121:509-512 Set 16: Vectors and Arrays CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 ed on slides created by Bjarne Stroustrup and Jennifer Welch

Transcript of CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17:...

Page 1: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121-200Introduction to Program Design and ConceptsJ. Michael MooreSpring 2015Set 17: Vectors and Arrays

1Based on slides created by Bjarne Stroustrup and Jennifer Welch

Page 2: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Vector, Take 1, Revisitedclass vector { int sz; double* elem;public: vector(int s) : sz{s}, elem{ new double[s] } { } ~vector() { delete[] elem; } double get(int n) { return elem[n]; } void set(int n, double v) { elem[n] = v; } int size() const { return sz; }};

2

Page 3: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Problem with One-Argument Constructors

• A constructor with a single argument defines an implicit conversion from the argument type to the constructor’s type

• Since our vector’s constructor takes an int as an argument, we get an implicit conversion from int to vector:vector v1 = 7; // v1 has 7 elements, each with value 0

andvoid f(vector v) { /* ... */ }/*... */

f(7); // calls f() with a vector of 7 elements

• This is usually not what we want! Very error-prone

3

Page 4: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Explicit Constructors

• To avoid such unwanted implicit conversions, declare one-argument constructors as explicit:

class vector { // ...public: explicit vector(int s); // ...};

• Now we get a compile-time error withvector v1 = 7;

andf(7);

4

Page 5: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copying Vectorvoid f(int n) { vector v(n); vector v2 = v; // What happens? // What do we want to happen? vector v3; v3 = v; // What happens? // What do we want to happen? // ...}

• Standard vector makes copies of v in both these cases, and all memory is returned to the free store when f returns

• How can we make sure this happens?

5

Page 6: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Default Copying Problem #1• The language default is that assignment causes all

the data members to be copied• But the data pointed to by pointers is not copied!• Disaster when f returns, as v1’s elements are deleted

twice (by the destructor)

void f(int n) { vector v1(n); vector v2 = v1;}

6

3

3

v1:

v2:

Page 7: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Default Copying Problem #2• Disaster when f returns, as v1’s elements are deleted

twice (by the destructor)• And, there is a memory leak: v2’s elements are not

deletedvoid f(int n) { vector v1(n); vector v2(4); v2 = v1;}

7

3

4 3

v1:

v2:

2nd

1st

Page 8: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copying• To avoid these problems, we have to write our

own code for– copy constructor: what should happen when a

new vector is declared using a pre-existing one– copy assignment: what should happen when we

assign one (pre-existing) vector to another (pre-existing) vector

• We have to make sure that the data in the array is copied, not just the pointer to the array, and we have to make sure there is no memory leak

8

Page 9: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copy Constructor

• We make an additional constructor for vector, which takes as an argument another vector

vector(const vector& a) : sz{a.sz}, elem { new double[a.sz] }{ // copy data from a into newly allocated space for (int i = 0; i < sz; ++i) elem[i] = a.elem[i];}

• Now the codevector v2 = v;

will initialize v2 by calling vector’s copy constructor with v as its argument.

9

Page 10: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copy with Copy Constructorvoid f(int n) { vector v1(n); vector v2 = v1;}

• The destructor correctly deletes all elements when f returns (once for each vector)

10

3

3

v1:

v2:

Page 11: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Should the Copy Constructor be Explicit?

• Not if we want the syntax “vector v2 = v1” to work; in this case we want the implicit conversion from one vector to another

• Also, if the copy constructor were explicit, we would not be able to pass a vector by value

• If the copy constructor were made explicit, then we would have to use this syntax to make a vector by copying from another vector:vector v2(v1); // call the constructor that // takes a vector argument

11

Page 12: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copy Assignment• For assigning to a pre-existing vector, we must

overload the assignment operator = to do the right thing

12

vector& operator=(const vector& a) { // allocate new space and copy a’s elements to it: double* p = new double[a.sz]; for (int i = 0; i < a.sz; ++i) [i] = a.elem[i]; delete[] elem; // deallocate old space sz = a.sz; // set new size elem = p; // set pointer to new elements return *this; // return a self-reference}

• In every member function, the identifier this is a pointer that points to the object for which the member function was called

Page 13: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Copy with Copy Assignmentvoid f(int n) { vector v1; // pushback 6, 24 and 42 vector v2(4); v2 = v1;}

13

3 6 4224

4 3

v1:

v2:

2nd

1st

42246

delete[ ]d by =

No memory Leak

Page 14: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Shallow vs. Deep Copy• Shallow copy: copies only a pointer; the two pointers now

refer to the same object– Examples: pointers, references

• Deep copy: also copy what the pointer points to; the two pointers now refer to distinct objects– Examples: vector, string,…– Requires copy constructors and copy assignments for container classes– Must copy “all the way down” if there are more levels in the object

14

x:

y: Copy of y:y:

Copy of x:x:Copy of x:

Shallow copy Deep copy

Page 15: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Deep Copy

vector<int> v1 {2,4};vector<int> v2 = v1;v2[0] = 3;

Shallow Copy

int b = 9;int& r1 = b;int& r2 = r1;r2 = 7;

15

4

v1:

2

2

4 2 3

v2: 2 9 7r1:r2: b:

Shallow vs. Deep Copy Examples

Page 16: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Move Constructor and Move Assignment

• Thanks to innovations on C++11, these functions can be provided to move (instead of copy)– speeds up performance by avoiding unnecessary

copying• We will not cover them, however

– read the texbook and see textbook slides if you are interested

16

Page 17: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Essential Operations• Constructors

– with argument(s): to initialize the object as we wish, perhaps establish some invariant

– with no arguments (default constructor): needed if we want to make objects of the class without specifying an initializer, e.g., to put objects into a vector (“vector<int> vi(10);”)

• Destructor: needed if the class acquires resources (e.g., memory on the free store); might be needed if it has a pointer/reference member– base class should have a virtual destructor

• Copy constructor and copy assignment: needed if the class has a destructor; if an object has acquired a resource then usually deep copy is needed

• Move constructor and move assignment: needed if the class has a destructor; deep copy can be expensive

17

Page 18: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Arrays• Arrays don’t have to be on the free store:char ac[7]; // global array, in static storage, // lives “forever”int max = 100;int ai[max]; // another global array

int f(int n) { char lc[20]; // local array, on stack, // lives until end of scope int li[60]; // another local array double lx[n]; // error! size of a local array // must be known at compile time}

18

Page 19: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Recall Address-of Operator &• You can get a pointer to any object, not just

those on the free storeint a;char ac[20];void f(int n) { int b; int* p = &b; p = &a; char* pc = ac; // array name is a pointer to first element pc = &ac[0]; // equivalent to pc = ac pc = &ac[n]; // pointer to ac’s n-th element // Warning! No range checking}

19

Page 20: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Arrays (Often) Convert to Pointersvoid f(int pi[]) // same as void f(int* pi){ int a[] = { 1, 2, 3, 4 }; int b[] = a; // error! copy (constructor) isn’t defined for arrays b = pi; // error! copy (assignment) isn’t defined for arrays pi = a; // OK but doesn’t copy; pi points to a’s first element; // is this a memory leak? Maybe int* p = a; // p points to a’s first element int* q = pi; // q points to a’s first element}

20

1

pi:

a: 2 3 4

p:

1st

2nd

q:

Page 21: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Arrays Don’t Know Their Own Sizevoid f(int pi[], int n, char pc[])// same as void f(int* pi, int n, char* pc)// Warning! Very dangerous code. Do not emulate! Never// “hope” that sizes will be correct{ char buf1[200]; strcpy(buf1,pc); // copy chars from pc into buf1; strcpy // stops when a ‘\0’ char is found; // hope that pc holds < 200 chars strncpy(buf1,pc,200); // copy 200 chars from pc to buf1, // padded if necessary, but final // ‘\0’ is not guaranteed int buf2[300]; // can’t say int buf2[n] since n is a variable if (300 < n) error(“not enough space”); for (int i = 0; i < n; ++i) buf2[i] = pi[i]; // hope that pi has // space for n ints}

21

Page 22: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Array and Pointer Pitfallschar* f() { char ch[20]; char* p = &ch[90]; // ... *p = ‘a’; // we don’t know what this will overwrite char* q; // forgot to initialize *q = ‘b’; // we don’t know what this will overwrite return &ch[10]; // Oops! ch disappears upon return // from f(); an infamous “dangling

pointer”}void g() { char* pp = f(); // ... *pp = ‘c’; // we don’t know what this will overwrite; // f’s ch is gone after f’s return}

22

Page 23: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

So Why Bother with Arrays?• They are all that C has

– lots of C code “out there” (billions of lines)– lots of C++ code in C style (hundreds of millions of line)– You’ll eventually encounter code full of arrays and pointers

• They represent primitive memory in C++ programs– we need them (mostly on free store allocated by new) to

implement better container types, like vector

• Avoid arrays whenever you can– largest single source of bugs in C and (unnecessarily) in C++

programs– among the largest sources of security violations, usually

(avoidable) buffer overflows

23

Page 24: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Accessing Elements in Our Vector• So far, we are using member functions set and get:for (int i = 0; i < v.size(); ++i) { v.set(i,i); cout << v.get(i);}

• But we would prefer to use square brackets:for (int i = 0; i < v.size(); ++i) { v[i] = i; cout << v[i];}

• How can we do that?

24

1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.00.0 9.010

Page 25: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Using Pointers for Accessing Vector Elements

• We can override the [] operator inside the vector class:double* operator[](int n)// return pointer to n-th element of elem array{ return &elem[n]; // return address}

• But we need to use the dereference operation *:for (int i = 0; i < v.size(); ++i) { *v[i] = i; cout << *v[i]}

• Still not what we want

25

Page 26: CSCE 121-200 Introduction to Program Design and Concepts J. Michael Moore Spring 2015 Set 17: Vectors and Arrays 1 Based on slides created by Bjarne Stroustrup.

CSCE 121:509-512 Set 16: Vectors and Arrays

Using References for Accessing Vector Elements

• We can override the [] operator inside the vector class like this:double& operator[](int n)// return reference to n-th element of elem array{ return elem[n]; // return reference}

• Now we get what we want (no need to use dereference operator * since references are automatically dereferenced):

for (int i = 0; i < v.size(); ++i) { v[i] = i; cout << v[i]}

26