30
Lecture 11 Lecture 11 vector vector and Free Store and Free Store Bjarne Stroustrup Bjarne Stroustrup www.stroustrup.com/Programming www.stroustrup.com/Programming

Lecture 11 vector and Free Store Bjarne Stroustrup

Embed Size (px)

Citation preview

Page 1: Lecture 11 vector and Free Store Bjarne Stroustrup

Lecture 11Lecture 11vectorvector and Free Store and Free Store

Bjarne Stroustrup Bjarne Stroustrup www.stroustrup.com/Programmingwww.stroustrup.com/Programming

Page 2: Lecture 11 vector and Free Store Bjarne Stroustrup

OverviewOverview

Vector revisitedVector revisited How are they implemented?How are they implemented?

Pointers and free storePointers and free store Allocation (new)Allocation (new) Access Access

Arrays and subscripting: []Arrays and subscripting: [] Dereferencing: *Dereferencing: *

Deallocation (delete)Deallocation (delete) DestructorsDestructors Copy constructor and copy assignmentCopy constructor and copy assignment ArraysArrays Array and pointer problemsArray and pointer problems Changing sizeChanging size TemplatesTemplates Range checking and exceptionsRange checking and exceptions

33Stroustrup/ProgrammingStroustrup/Programming

Page 3: Lecture 11 vector and Free Store Bjarne Stroustrup

VectorVector Vector is the most useful containerVector is the most useful container

SimpleSimple Compactly stores elements of a given typeCompactly stores elements of a given type Efficient accessEfficient access Expands to hold any number of elementsExpands to hold any number of elements Optionally range-checked accessOptionally range-checked access

How is that done?How is that done? That is, how is vector implemented?That is, how is vector implemented?

We'll answer that gradually, feature after featureWe'll answer that gradually, feature after feature Vector is the default containerVector is the default container

prefer vector for storing elements unless there's a good prefer vector for storing elements unless there's a good reason not toreason not to

44Stroustrup/ProgrammingStroustrup/Programming

Page 4: Lecture 11 vector and Free Store Bjarne Stroustrup

Building from the ground upBuilding from the ground up The hardware provides memory and addressesThe hardware provides memory and addresses

Low levelLow level UntypedUntyped Fixed-sizedFixed-sized No checkingNo checking As fast as the hardware architects can make itAs fast as the hardware architects can make it

The application builder needs something like a vectorThe application builder needs something like a vector Higher-level operationsHigher-level operations Type checkedType checked Size varies (as we get more data)Size varies (as we get more data) Run-time checkingRun-time checking Close-to optimally fastClose-to optimally fast

55Stroustrup/ProgrammingStroustrup/Programming

Page 5: Lecture 11 vector and Free Store Bjarne Stroustrup

Building from the ground upBuilding from the ground up

At the lowest level, close to the hardware, life’s simple and At the lowest level, close to the hardware, life’s simple and brutalbrutal You have to program everything yourselfYou have to program everything yourself You have no type checking to help youYou have no type checking to help you Run-time errors are found when data is corrupted or the program crashesRun-time errors are found when data is corrupted or the program crashes

We want to get to a higher level as quickly as we canWe want to get to a higher level as quickly as we can To become productive and reliableTo become productive and reliable To use a language “fit for humans”To use a language “fit for humans” The alternative to understanding is to believe in “magic”The alternative to understanding is to believe in “magic” The techniques for building vector are the ones underlying all higher-level The techniques for building vector are the ones underlying all higher-level

work with data structureswork with data structures

66Stroustrup/ProgrammingStroustrup/Programming

Page 6: Lecture 11 vector and Free Store Bjarne Stroustrup

VectorVector

A A vectorvector Can hold an arbitrary number of elementsCan hold an arbitrary number of elements

Up to whatever physical memory and the operating system can handleUp to whatever physical memory and the operating system can handle That number can vary over timeThat number can vary over time

E.g. by using E.g. by using push_back()push_back() ExampleExample

vector<double> age(4);vector<double> age(4);age[0]=.33; age[1]=22.0; age[2]=27.2; age[3]=54.2;age[0]=.33; age[1]=22.0; age[2]=27.2; age[3]=54.2;

77

4

0.33 22.0 27.2 54.2

age:

age[0]: age[1]: age[2]: age[3]:

Stroustrup/ProgrammingStroustrup/Programming

Page 7: Lecture 11 vector and Free Store Bjarne Stroustrup

VectorVector

// // a very simplifieda very simplified vector vector of of doubledoubles (like s (like vector<double>vector<double>):):class vector {class vector {

int sz;int sz; // // the number of elements (“the size”)the number of elements (“the size”)double* elem;double* elem; // // pointer to the first elementpointer to the first element

public:public:vector(int s);vector(int s); // // constructor: allocateconstructor: allocate s s elements,elements,

// // letlet elem elem point to thempoint to them// // store store ss in in szsz

int size() const { return sz; }int size() const { return sz; } // // the current sizethe current size};};

* * means “pointer to” someans “pointer to” so double*double* is a “pointer tois a “pointer to doubledouble”” What is a “pointer”?What is a “pointer”? how do we make a pointer “point to” elements?how do we make a pointer “point to” elements? How do we “allocate” elements?How do we “allocate” elements?

88Stroustrup/ProgrammingStroustrup/Programming

Page 8: Lecture 11 vector and Free Store Bjarne Stroustrup

Pointer valuesPointer values

Pointer values are memory addressesPointer values are memory addresses Think of them as a kind of integer valuesThink of them as a kind of integer values The first byte of memory is 0, the next 1, and so onThe first byte of memory is 0, the next 1, and so on

99

0 1 2 2^20-1

7

p2 *p2

A pointer points to an object of a given typeA pointer points to an object of a given type E.g. a E.g. a double*double* points to a points to a doubledouble, not to a , not to a stringstring

A pointer’s type determines how the memory referred to by A pointer’s type determines how the memory referred to by the pointer’s value is usedthe pointer’s value is used E.g. what a E.g. what a double*double* points to can be added not, say, concatenated points to can be added not, say, concatenated

Stroustrup/ProgrammingStroustrup/Programming

Page 9: Lecture 11 vector and Free Store Bjarne Stroustrup

Vector Vector (constructor)(constructor)

vector::vector(int s)vector::vector(int s) // // vector's constructorvector's constructor:sz(s),:sz(s), // // store the sizestore the size s s inin sz sz elem(new double[s])elem(new double[s]) // // allocateallocate s double s doubles on the free stores on the free store

// // store a pointer to thosestore a pointer to those double doubles in s in elemelem{ { }}// // Note:Note: new new does not initialize elements (but the standard vector does)does not initialize elements (but the standard vector does)

1010

Free store:

4

new allocates memory from the free store and returns a pointer to the allocated memory

A pointer

sz: elem:

Stroustrup/ProgrammingStroustrup/Programming

Page 10: Lecture 11 vector and Free Store Bjarne Stroustrup

The computer’s memoryThe computer’s memory

As a program sees itAs a program sees it Local variables “lives on the stack”Local variables “lives on the stack” Global variables are “static data”Global variables are “static data” The executable code are in “the code section”The executable code are in “the code section”

1111Stroustrup/ProgrammingStroustrup/Programming

Page 11: Lecture 11 vector and Free Store Bjarne Stroustrup

The free storeThe free store(sometimes called "the heap")(sometimes called "the heap")

You request memory "to be allocated" "on the free store" by the You request memory "to be allocated" "on the free store" by the newnew operator operator The The newnew operator returns a pointer to the allocated memory operator returns a pointer to the allocated memory A pointer is the address of the first byte of the memoryA pointer is the address of the first byte of the memory For exampleFor example

int* p = new int;int* p = new int; // // allocate one uninitialized allocate one uninitialized int int// // int* int* means “pointer tomeans “pointer to int int””

int* q = new int[7];int* q = new int[7]; // // allocate seven uninitializedallocate seven uninitialized int intss// // “an array of 7 “an array of 7 intints”s”

double* pd = new double[n];double* pd = new double[n]; // // allocateallocate n n uninitialized uninitialized doubledoubless A pointer points to an object of its specified typeA pointer points to an object of its specified type A pointer does A pointer does notnot know how many elements it points to know how many elements it points to

1212

p:

q:Stroustrup/ProgrammingStroustrup/Programming

Page 12: Lecture 11 vector and Free Store Bjarne Stroustrup

AccessAccess

Individual elementsIndividual elementsint* p1 = new int;int* p1 = new int; // // get (allocate) a new uninitialized int get (allocate) a new uninitialized int int* p2 = new int(5);int* p2 = new int(5); // // get a new int initialized to 5get a new int initialized to 5

int x = *p2;int x = *p2; //// get/read the value pointed to by p2get/read the value pointed to by p2//// (or “get the contents of what p2 points to”)(or “get the contents of what p2 points to”)//// in this case, the integer 5in this case, the integer 5

int y = *p1;int y = *p1; // undsefined: y gets an undefined value; don’t do that // undsefined: y gets an undefined value; don’t do that

1313

5

p2:

???

p1:

Stroustrup/ProgrammingStroustrup/Programming

Page 13: Lecture 11 vector and Free Store Bjarne Stroustrup

AccessAccess

Arrays (sequences of elements)Arrays (sequences of elements)int* p3 = new int[5];int* p3 = new int[5]; // // get (allocate) 5 get (allocate) 5 intints s

// // array elements are numbered 0, 1, array elements are numbered 0, 1, 2, …2, …

p3[0] = 7;p3[0] = 7; // // write to (“set”) the 1write to (“set”) the 1stst element of p3 element of p3p3[1] = 9;p3[1] = 9;

int x2 = p3[1];int x2 = p3[1]; //// get the value of the 2get the value of the 2ndnd element of p3 element of p3

int x3 = *p3;int x3 = *p3; // // we can also use the dereference operator * for an we can also use the dereference operator * for an arrayarray

//// *p3 means p3[0] (and vice versa)*p3 means p3[0] (and vice versa) 1414

7 9

p3:

Stroustrup/ProgrammingStroustrup/Programming

Page 14: Lecture 11 vector and Free Store Bjarne Stroustrup

Why use free store?Why use free store? To allocate objects that have to outlive the function To allocate objects that have to outlive the function

that creates them:that creates them: For exampleFor example

double* make(int i)double* make(int i)

{{

return new double[i];return new double[i];

}}

Another example: vector's constructorAnother example: vector's constructor

1515Stroustrup/ProgrammingStroustrup/Programming

Page 15: Lecture 11 vector and Free Store Bjarne Stroustrup

Pointer valuesPointer values

Pointer values are memory addressesPointer values are memory addresses Think of them as a kind of integer valuesThink of them as a kind of integer values The first byte of memory is 0, the next 1, and so onThe first byte of memory is 0, the next 1, and so on

1616

// you can see pointer value (but you rarely need/want to):

char* p1 = new char('c'); // allocate a char and initialize it to 'c'

int* p2 = new int(7); // allocate an int and initialize it to 7

cout << "p1==" << p1 << " *p1==" << *p1 << "\n"; // p1==??? *p1==c

cout << "p2==" << p2 << " *p2==" << *p2 << "\n"; // p2==??? *p2=7

0 1 2 2^20-1

7

p2 *p2

Stroustrup/ProgrammingStroustrup/Programming

Page 16: Lecture 11 vector and Free Store Bjarne Stroustrup

AccessAccess

A pointer does A pointer does notnot know the number of elements that know the number of elements that it's pointing to (only the address of the first element)it's pointing to (only the address of the first element)double* p1 = new double;double* p1 = new double;*p1 = 7.3;*p1 = 7.3; // // okokp1[0] = 8.2;p1[0] = 8.2; // // okokp1[17] = 9.4;p1[17] = 9.4; // // ouch! Undetected errorouch! Undetected errorp1[-4] = 2.4;p1[-4] = 2.4; // // ouch! Another undetected errorouch! Another undetected error

double* p2 = new double[100];double* p2 = new double[100];*p2 = 7.3;*p2 = 7.3; // // okokp2[17] = 9.4;p2[17] = 9.4; // // okokp2[-4] = 2.4;p2[-4] = 2.4; // // ouch! Undetected errorouch! Undetected error

1717

7.3

8.27.3

p1:

p2:

Stroustrup/ProgrammingStroustrup/Programming

Page 17: Lecture 11 vector and Free Store Bjarne Stroustrup

AccessAccess

A pointer does A pointer does notnot know the number of elements that know the number of elements that it's pointing toit's pointing todouble* p1 = new double;double* p1 = new double;double* p2 = new double[100];double* p2 = new double[100];

p1[17] = 9.4; //p1[17] = 9.4; // error (obviously)error (obviously)

p1 = p2; p1 = p2; // // assign the value of assign the value of p2p2 to to p1p1

p1[17] = 9.4; //p1[17] = 9.4; // now ok: now ok: p1p1 now points to the array of 100 now points to the array of 100 doublesdoubles

1818

p1:

p2:

p1:

(after the assignment)

[0]: [99]:

Stroustrup/ProgrammingStroustrup/Programming

Page 18: Lecture 11 vector and Free Store Bjarne Stroustrup

AccessAccess A pointer A pointer doesdoes know the type of the object that it's know the type of the object that it's

pointing topointing toint* pi1 = new int(7);int* pi1 = new int(7);int* pi2 = pi1;int* pi2 = pi1; // // ok:ok: pi2 pi2 points to the same object aspoints to the same object as pi1 pi1double* pd = pi1;double* pd = pi1; // // error: can't assign anerror: can't assign an int* int* to ato a double* double*char* pc = pi1;char* pc = pi1; // // error: can't assign anerror: can't assign an int* int* to ato a char* char* There are no implicit conversions between a pointer to one value There are no implicit conversions between a pointer to one value

type to a pointer to another value typetype to a pointer to another value type However, there are implicit conversions between value types:However, there are implicit conversions between value types:

*pc = 8;*pc = 8; // // ok: we can assign anok: we can assign an int int to ato a char char*pc = *pi1;*pc = *pi1; // // ok: we can assign anok: we can assign an int int to ato a char char

1919

7 7

pi1:pc:

Stroustrup/ProgrammingStroustrup/Programming

Page 19: Lecture 11 vector and Free Store Bjarne Stroustrup

Pointers, arrays, and vectorPointers, arrays, and vector NoteNote

With pointers and arrays we are "touching" hardware With pointers and arrays we are "touching" hardware directly with only the most minimal help from the directly with only the most minimal help from the language. Here is where serious programming errors can language. Here is where serious programming errors can most easily be made, resulting in malfunctioning programs most easily be made, resulting in malfunctioning programs and obscure bugsand obscure bugs

Be careful and operate at this level only when you really need toBe careful and operate at this level only when you really need to

vector is one way of getting almost all of the flexibility and vector is one way of getting almost all of the flexibility and performance of arrays with greater support from the performance of arrays with greater support from the language (read: fewer bugs and less debug time).language (read: fewer bugs and less debug time).

2020Stroustrup/ProgrammingStroustrup/Programming

Page 20: Lecture 11 vector and Free Store Bjarne Stroustrup

Vector Vector (construction and primitive access)(construction and primitive access)

// // a very simplifieda very simplified vector vector of of doubledoubless::

class vector {class vector {

int sz;int sz; // // the sizethe size

double* elem;double* elem; // // a pointer to the elementsa pointer to the elements

public:public:

vector(int s) :sz(s), elem(new double[s]) { }vector(int s) :sz(s), elem(new double[s]) { } // // constructorconstructor

double get(int n) { return elem[n]; } double get(int n) { return elem[n]; } // // access: readaccess: read

void set(int n, double v) { elem[n]=v; }void set(int n, double v) { elem[n]=v; } //// access: writeaccess: write

int size() const { return sz; }int size() const { return sz; } // // the current sizethe current size

};};

vector v(10);vector v(10);

for (int i=0; i<v.size(); ++i) { v.set(i,i); cout << v.get(i) << ' '; }for (int i=0; i<v.size(); ++i) { v.set(i,i); cout << v.get(i) << ' '; }

2121

1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.00.0 9.010Stroustrup/ProgrammingStroustrup/Programming

Page 21: Lecture 11 vector and Free Store Bjarne Stroustrup

A problem: memory leakA problem: memory leak

double* calc(int result_size, int max)double* calc(int result_size, int max){{

double* p = new double[max];double* p = new double[max]; // // allocate anotherallocate another max double max doubless//// i.e., get i.e., get max doublemax doubles from the free s from the free

storestoredouble* result = new double[result_size];double* result = new double[result_size];// // …… useuse p p to calculate results to be put into calculate results to be put in result result … …return result;return result;

}}

double* r = calc(200,100);double* r = calc(200,100); // // oops! We “forgot” to give the memory oops! We “forgot” to give the memory //// allocated for p back to the free storeallocated for p back to the free store

Lack of de-allocation (usually called "memory leaks") can be a Lack of de-allocation (usually called "memory leaks") can be a serious problem in real-world programsserious problem in real-world programs

A program that must run for a long time can't afford any A program that must run for a long time can't afford any memory leaksmemory leaks 2222Stroustrup/ProgrammingStroustrup/Programming

Page 22: Lecture 11 vector and Free Store Bjarne Stroustrup

A problem: memory leakA problem: memory leak

double* calc(int result_size, int max)double* calc(int result_size, int max){{

int* p = new double[max]; int* p = new double[max]; // // allocate anotherallocate another max double max doubless//// i.e., get i.e., get max doublemax doubles from the free s from the free

storestoredouble* result = new double[result_size];double* result = new double[result_size];// // …… useuse p p to calculate results to be put into calculate results to be put in result … result …delete[ ] p;delete[ ] p; // // de-allocate (free) that arrayde-allocate (free) that array

//// i.e., give the array back to the free i.e., give the array back to the free storestorereturn result;return result;

}}

double* r = calc(200,100);double* r = calc(200,100);// // use ruse rdelete[ ] r;delete[ ] r; //// easy to forgeteasy to forget 2323Stroustrup/ProgrammingStroustrup/Programming

Page 23: Lecture 11 vector and Free Store Bjarne Stroustrup

Memory leaksMemory leaks

A program that needs to run "forever" can't afford any memory leaksA program that needs to run "forever" can't afford any memory leaks An operating system is an example of a program that "runs forever"An operating system is an example of a program that "runs forever"

If a function leaks 8 bytes every time it is called, how many days can it If a function leaks 8 bytes every time it is called, how many days can it run before it has leaked/lost a megabyte?run before it has leaked/lost a megabyte? Trick question: not enough data to answer, but about 130,000 callsTrick question: not enough data to answer, but about 130,000 calls

All memory is returned to the system at the end of the programAll memory is returned to the system at the end of the program If you run using an operating system (Windows, Unix, whatever)If you run using an operating system (Windows, Unix, whatever)

Program that runs to completion with predictable memory usage may Program that runs to completion with predictable memory usage may leak without causing problemsleak without causing problems i.e.,i.e., memory leaks aren't "good/bad" but they can be a problem in memory leaks aren't "good/bad" but they can be a problem in

specific circumstancesspecific circumstances

2424Stroustrup/ProgrammingStroustrup/Programming

Page 24: Lecture 11 vector and Free Store Bjarne Stroustrup

Memory leaksMemory leaks

Another way to get a Another way to get a memory leakmemory leak

void f()void f(){{

double* p = new double[27];double* p = new double[27];// // ……p = new double[42];p = new double[42];// // ……delete[] p;delete[] p;

}}

// // 11stst array (of 27 doubles) leaked array (of 27 doubles) leaked

2525

p:

2nd value

1st value

Stroustrup/ProgrammingStroustrup/Programming

Page 25: Lecture 11 vector and Free Store Bjarne Stroustrup

Memory leaksMemory leaks

How do we systematically and simply avoid memory How do we systematically and simply avoid memory leaks?leaks? don't mess directly with don't mess directly with new new and and deletedelete

Use Use vectorvector, etc., etc.

Or use a garbage collectorOr use a garbage collector A garbage collector is a program the keeps track of all of your A garbage collector is a program the keeps track of all of your

allocations and returns unused free-store allocated memory to the allocations and returns unused free-store allocated memory to the free store (not covered in this course; see free store (not covered in this course; see http://www.research.att.com/~bs/C++.html)http://www.research.att.com/~bs/C++.html)

Unfortunately, even a garbage collector doesn’t prevent all leaksUnfortunately, even a garbage collector doesn’t prevent all leaks

2626Stroustrup/ProgrammingStroustrup/Programming

Page 26: Lecture 11 vector and Free Store Bjarne Stroustrup

A problem: memory leakA problem: memory leak

void f(int x)void f(int x){{

vector v(x);vector v(x); // // define adefine a vector vector//// (which allocates (which allocates xx doubledoubles on the free stores on the free store))

// // …… useuse v v ……

// // give the memory allocated by give the memory allocated by v v back to the free storeback to the free store// // but how? (but how? (vectorvector's 's elemelem data member is private) data member is private)

}}

2727Stroustrup/ProgrammingStroustrup/Programming

Page 27: Lecture 11 vector and Free Store Bjarne Stroustrup

Vector Vector (destructor)(destructor)

// // a very simplifieda very simplified vector vector of of doubledoubles:s:class vector {class vector {

int sz;int sz; // // the sizethe sizedouble* elem;double* elem; // // a pointer to the elementsa pointer to the elements

public:public:vector(int s) vector(int s) // // constructor: allocates/acquires memoryconstructor: allocates/acquires memory

:sz(s), elem(new double[s]) { } :sz(s), elem(new double[s]) { } ~vector()~vector() // // destructor: de-allocates/releases memorydestructor: de-allocates/releases memory

{ delete[ ] elem; }{ delete[ ] elem; }// // ……

};};

NNote: this is an example of a general and important technique:ote: this is an example of a general and important technique: acquire resources in a constructoracquire resources in a constructor release them in the destructorrelease them in the destructor

Examples of resources: memory, files, locks, threads, sockets Examples of resources: memory, files, locks, threads, sockets 2828Stroustrup/ProgrammingStroustrup/Programming

Page 28: Lecture 11 vector and Free Store Bjarne Stroustrup

A problem: memory leakA problem: memory leak

void f(int x)void f(int x)

{{

int* p = new int[x];int* p = new int[x]; // // allocate allocate x intx intss

vector v(x);vector v(x); // // define adefine a vector vector (which allocates another(which allocates another x x ints)ints)

// // …… useuse p p andand v v ……

delete[ ] p;delete[ ] p; // // deallocate the array pointed to bydeallocate the array pointed to by p p

// // the memory allocated bythe memory allocated by v v is implicitly deleted here byis implicitly deleted here by vector vector's destructor's destructor

}}

The The delete delete now looks verbose and uglynow looks verbose and ugly How do we avoid forgetting to How do we avoid forgetting to delete[ ] pdelete[ ] p?? Experience shows that we often forgetExperience shows that we often forget

Prefer Prefer deletedeletes in destructorss in destructors

2929Stroustrup/ProgrammingStroustrup/Programming

Page 29: Lecture 11 vector and Free Store Bjarne Stroustrup

Free store summaryFree store summary Allocate using Allocate using newnew

New allocates an object on the free store, sometimes initializes it, and New allocates an object on the free store, sometimes initializes it, and returns a pointer to itreturns a pointer to it

int* pi = new int;int* pi = new int; //// default initialization (none for default initialization (none for intint)) char* pc = new char('a');char* pc = new char('a'); //// explicit initializationexplicit initialization double* pd = new double[10];double* pd = new double[10]; //// allocation of (uninitialized) allocation of (uninitialized)

arrayarray New throws a New throws a bad_allocbad_alloc exception if it can't allocate exception if it can't allocate

Deallocate using Deallocate using deletedelete and and delete[ ]delete[ ] deletedelete and and delete[ ]delete[ ] return the memory of an object allocated by return the memory of an object allocated by newnew to to

the free store so that the free store can use it for new allocationsthe free store so that the free store can use it for new allocations delete pi;delete pi; //// deallocate an individual objectdeallocate an individual object delete pc;delete pc; //// deallocate an individual objectdeallocate an individual object delete[ ] pd;delete[ ] pd; //// deallocate an arraydeallocate an array

Delete of a zero-valued pointer ("the null pointer") does nothingDelete of a zero-valued pointer ("the null pointer") does nothing char* p = 0;char* p = 0; delete p;delete p; //// harmlessharmless

3030Stroustrup/ProgrammingStroustrup/Programming

Page 30: Lecture 11 vector and Free Store Bjarne Stroustrup

Next lectureNext lecture The next lecture discusses copying and arraysThe next lecture discusses copying and arrays

3131Stroustrup/ProgrammingStroustrup/Programming