lecture 11 vector and free store
DESCRIPTION
Lecture 11 vector and Free Store. Bjarne Stroustrup www.stroustrup.com/Programming. Overview. Vector revisited How are they implemented? Pointers and free store Allocation (new) Access Arrays and subscripting: [] Dereferencing: * Deallocation (delete) Destructors - PowerPoint PPT PresentationTRANSCRIPT
Lecture 11Lecture 11vectorvector and Free Store and Free Store
Bjarne Stroustrup Bjarne Stroustrup www.stroustrup.com/Programmingwww.stroustrup.com/Programming
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Next lectureNext lecture The next lecture discusses copying and arraysThe next lecture discusses copying and arrays
3131Stroustrup/ProgrammingStroustrup/Programming