Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSCE 121:509-512 Introduction to Program Design and Concepts, Honors Dr. J. Michael Moore Spring 2015 Set 16: Vector and Free Store CSCE 121-200: Set 16:

Similar presentations


Presentation on theme: "CSCE 121:509-512 Introduction to Program Design and Concepts, Honors Dr. J. Michael Moore Spring 2015 Set 16: Vector and Free Store CSCE 121-200: Set 16:"— Presentation transcript:

1 CSCE 121:509-512 Introduction to Program Design and Concepts, Honors Dr. J. Michael Moore Spring 2015 Set 16: Vector and Free Store CSCE 121-200: Set 16: Vector and Free Store 1 Based on slides created by Bjarne Stroustrup and Jennifer Welch

2 CSCE 121:509-512 Set 16: Vector and Free Store Vector’s Virtues Vector is most useful container: use it to store elements unless you have a good reason not to – Simple – Compactly stores element of a given type – Efficient access – Expands to hold any number of elements – Option for range checking How is it done? 2

3 CSCE 121:509-512 Set 16: Vector and Free Store How is Vector Implemented? We will study this and learn about Pointers Free store: allocating, accessing, deallocating Destructors Initialization, copying and moving Arrays Changing size Templates Range checking and exceptions 3

4 CSCE 121:509-512 Set 16: Vector and Free Store Rationale for Studying Vector Implementation Real-world case study to motivate these concepts and their C++ instantiations Understand bridge from low-level hardware to high-level services Hardware only provides memory and addresses: – Untyped – Fixed size – No checking 4

5 CSCE 121:509-512 Set 16: Vector and Free Store Review of Computer Memory 5 Local variables “live on the stack” Global variables are “static data” Executable code is in the “code section” Free store (heap) is subject of this lesson

6 CSCE 121:509-512 Set 16: Vector and Free Store Vector, Take 1 What is going on with double* ? 6 //very simplified vector of doubles class vector { int sz; // number of elements double* elem; // pointer to first element public: vector(int s); // constructor; more later int size() const { return sz; } };

7 CSCE 121:509-512 Set 16: Vector and Free Store Pointer Values Pointer values are memory addresses – Think of them as a kind of integer – The first byte of memory has address 0, the next 1, etc. – A pointer variable p can hold the address of a memory location A pointer points to an object of a given type – E.g., a double* points to a double, not to a string A pointer’s type determines how the memory referred to by the pointer’s value can be used 7 0122 20 -1 7600 p

8 CSCE 121:509-512 Set 16: Vector and Free Store Pointer Syntax and Terminology To declare a variable p as a pointer to an object of type int ( p holds the address of an object of type int ): int* p ; – Note: You can also say “ int *p; ” but be careful when declaring multiple variables on same line – “ int *px, py; ” makes px a pointer and py an int) To get to the object that p points to (to access its value), we have to dereference p : *p = 5; // changes memory whose address is stored // in p, not the data stored in location p int y = 4 + *p; // y holds 9 Pointers can point to object of any type 8

9 CSCE 121:509-512 Set 16: Vector and Free Store Pointer vs. Reference Think of a reference as an automatically dereferenced pointer – you do not need to use the * (dereference) operator to get to the value – thus it is an alternative name for an object Differences from pointer: – reference must be initialized – value of a reference cannot be changed after initialization (reference always refers to the same object) 9

10 CSCE 121:509-512 Set 16: Vector and Free Store Pointer vs. Reference Examples int x = 7; int y = 8; int* p = &x; *p = 9; p = &y; // OK: can change which object p points to int& r = x; x = 10; r = &y; // error: cannot change which object r // refers to 10

11 CSCE 121:509-512 Set 16: Vector and Free Store Pointer Hazards Pointers (are supposed to) hold addresses They really hold bit patterns that are interpreted as addresses If a pointer somehow holds arbitrary bits, it can refer to: – address that doesn’t exist – address that exists but is definitely not where you want to be! Reading from this (random) location returns garbage Writing to this (random) location corrupts memory Bad effects (run-time errors): – crash the operating system – cause memory protection exception – produce incorrect results 11

12 CSCE 121:509-512 Set 16: Vector and Free Store Mitigating Pointer Hazards Avoid Using Pointers When Possible – E.g., use vector instead of arrays Only use pointers in very constrained situations When you do use pointers, be sure to initialize them properly: int* pi = nullptr; // or NULL or 0 12

13 CSCE 121:509-512 Set 16: Vector and Free Store Pointing to Objects on the Stack You can use pointers to get the address of objects stored in the stack using the & (address-of) operator 13 int main() { int i; int *pi = nullptr; pi = &i; // pi gets address of i *pi = 502; // assigns to i cout << "i = " << i << endl; // outputs 502 cout << "pi = " << pi << endl; // outputs, e.g., 0x7fff503ebbb8 cout << "*pi = " << *pi << endl; // outputs 502 return 0; }

14 CSCE 121:509-512 Set 16: Vector and Free Store Pointing to Objects on the Heap An important use of pointers is to point to objects that are allocated on the heap (free store) 14

15 CSCE 121:509-512 Set 16: Vector and Free Store Dynamic Memory Allocation Use the operator new to allocate a chunk of memory on the heap – specify the type of object to be stored and – specify the number of objects of that type new returns a pointer to the first object in the chunk Memory allocated with new is not automatically deallocated! – you must do that explicitly yourself with the delete operator – thus you can allocate objects that outlive the function that creates them 15

16 CSCE 121:509-512 Set 16: Vector and Free Store Example Use of new int s = 100; double* dp = new double[s]; // Allocates space for 100 // consecutive doubles on the heap. // To check whether new was // successful: if (dp == 0) error(“new failed”); // Continue and use the space. // If you only want one double, // then leave off the [s] 16

17 CSCE 121:509-512 Set 16: Vector and Free Store Vector, Take 1, Constructor vector::vector(int s) // vector’s constructor : sz(s), // store the size s in data member sz elem(new double[s]) // allocate s consecutive doubles in free store, // store pointer to the first double in // data member elem {} // new does not initialize the elements (but the // standard vector does) 17 Free store: 4 A pointer sz:elem:

18 CSCE 121:509-512 Set 16: Vector and Free Store Accessing Memory Allocated on the Heap Individual objects allocated in a batch by new are accessed using the [ ] notation for indexing, starting at 0 int* pi = new int[5]; pi[0] = 7; pi[1] = 9; int x = pi[1]; int y = *pi; // means pi[0] 18

19 CSCE 121:509-512 Set 16: Vector and Free Store A Pointer Pitfall A pointer actually holds the address of a byte – the first byte of the object or sequence of objects A pointer does not know how many objects have been allocated – doesn’t know where to stop int* pi = new int[5]; int y = -3; pi[5] = 72; // compiles like a charm :( pi[-4] = 12; // ditto 19

20 CSCE 121:509-512 Set 16: Vector and Free Store Assigning a Pointer to a Pointer What happens in this case? double* p1 = new double; double* p2 = new double[100]; p1[17] = 9.4; // run-time or logic error p1 = p2; p1[17] = 9.4 // OK now the assignment “ p1 = p2 ” copies the data in p2 (the address of the start of the 100 doubles) into p1 20

21 CSCE 121:509-512 Set 16: Vector and Free Store Pointers and Types A pointer does know the type of the object that it is pointing to int* pi1 = new int(7); // initialize to 7 int* pi2 = pi1; // OK double* pd = pi1; // compile-time error char* pc = pi1; // compile-time error There are no implicit conversions between a pointer to one value type to a pointer to another value type 21

22 CSCE 121:509-512 Set 16: Vector and Free Store Pointer-Related Errors The following errors are often caused by uninitialized or otherwise invalid pointers: – segmentation fault – bus error – core dump 22

23 CSCE 121:509-512 Set 16: Vector and Free Store Vector, Take 1, Access 23 class vector { int sz; double* elem; public: vector(int s) : sz(s), elem(new double[s]) { } // constructor double get(int n) const { return elem[n]; } // access: read void set(int n, double v) { elem[n] = v; } // access: write int size() const { return sz; } // the current size }; //... vector v(10); for (int i = 0; i < v.size(); ++i) { v.set(i,i); cout << v.get(i); }

24 CSCE 121:509-512 Set 16: Vector and Free Store A Problem: Memory Leak We did not give the memory allocated for p back to the free store but there is no way to access it once calc is finished Memory leak (lack of deallocation) – can be a serious problem in real-world programs 24 double* calc(int result_size, int max) { double* p = new double[max]; double* result = new double[result_size]; // use p to calculate values to be put in result return result; } //... double* r = calc(200,100);

25 CSCE 121:509-512 Set 16: Vector and Free Store Memory Leaks A program that needs to run “forever” (e.g., an operating system) cannot afford any memory leaks – eventually memory leaks will use up all available memory All memory is returned to the system at the end of the program Programs that run to completion with predictable memory usage may leak without causing problems 25

26 CSCE 121:509-512 Set 16: Vector and Free Store Preventing Memory Leak: Deallocation Use operator delete (for single object) or delete[] (for multiple objects, i.e., array): double* calc(int result_size, int max) { int* p = new double[max]; double* result = new double[result_size]; // use p to calculate values to be put in result delete[] p; // deallocates memory pointed to by p return result; } //... double* r = calc(200,100); // use r delete[] r; // but this is easy to forget 26

27 CSCE 121:509-512 Set 16: Vector and Free Store Another Memory Leak void f() { double* p = new double[27]; //... p = new double[42]; //... delete[] p; } // first array // (of 27 doubles) // leaked 27 p: 2 nd value 1 st value

28 CSCE 121:509-512 Set 16: Vector and Free Store Preventing Memory Leaks More Systematically One option is to have the run-time system, instead of the programmer, find inaccessible memory and return it to the free store – called garbage collection – some languages, including Java, have this – C++ does not (efficiency issues) Another option, relevant to C++, is to avoid using new and delete except in very constrained ways – mostly rely on features, like vector, that do it for us 28

29 CSCE 121:509-512 Set 16: Vector and Free Store Vector, Take 1, Leaks Memory void f(int x) { // constructor allocates x doubles on the // free store vector v(x); //... use v... } // How can we give those x doubles back to // the free store before f returns? // v.elem is a private data member in vector 29

30 CSCE 121:509-512 Set 16: Vector and Free Store Destructor C++ classes allow us to define a special function, called a destructor Destructor is automatically called whenever a variable of that class goes out of scope – for example, when the function that defined the variable is about to return The destructor code can do “clean up” – most notably, it can delete any memory that has been allocated on the free store Destructor for class T is denoted ~T() 30

31 CSCE 121:509-512 Set 16: Vector and Free Store Vector, Take 1, Destructor // a very simplified vector of doubles class vector { int sz; double* elem; public: // constructor: vector(int s) : sz(s) elem(new double[s]) { } //... get, set, size... // destructor: ~vector() { delete[] elem; } }; 31

32 CSCE 121:509-512 Set 16: Vector and Free Store Important Resource Management Technique Acquire resources in a constructor Release resources in the destructor Examples of resources: memory files locks threads sockets 32

33 CSCE 121:509-512 Set 16: Vector and Free Store Comparing Code Styles Managing Memory Yourself void f(int x) { int* p = new int[x]; //... use p... delete[] p; } Managing Memory in Constructors and Destructors void f(int x) { vector v(x); //... use v... } 33

34 CSCE 121:509-512 Set 16: Vector and Free Store Free Store Summary: Allocation Allocate using new (preferably in a constructor) – new allocates an object on the free store, sometimes initializes it, and returns a pointer to it int* pi = new int; // default initialization // (none for int) char* pc = new char(‘a’); // explicit // initialization double* pd = new double[10]; // allocation of // (uninitialized) array –new throws a bad_alloc exception if it cannot allocate (out of memory) 34

35 CSCE 121:509-512 Set 16: Vector and Free Store Free Store Summary: Deallocation Deallocate using delete and delete[] (preferably in a destructor) –delete and delete[] return the memory of any object allocated by new to the free store for use in future allocations delete pi; // deallocate an individual object delete[] pd; // deallocate an array of objects – delete of a zero-valued pointer (“null pointer” or nullptr ) does nothing: char* p = nullptr; delete p; // harmless 35

36 CSCE 121:509-512 Set 16: Vector and Free Store Allocating a Vector on the Stack vs. Heap Allocate Vector on Stack vector v(5); v.set(0,10); cout << v.get(0); v.set(1,40); cout << v.get(1); Allocate Vector on Heap vector* pv = new vector(5); (*pv).set(0,20); cout << (*pv).get(0); // Parentheses necessary! // shorthand -> notation pv->set(1,40); cout get(1); 36

37 CSCE 121:509-512 Set 16: Vector and Free Store Allocating a Vector on the Stack vs. Heap The difference is where the “bookkeeping” goes ( sz and elem ) In both cases, the array of objects pointed to by elem is on the heap If vector is allocated on the stack ( vector v(5) ), then sz and elem are on stack If vector is allocated on the heap ( vector* pv = new vector(5) ), then sz and elem are on the heap 37

38 CSCE 121:509-512 Set 16: Vector and Free Store Deallocation of Vector Declared on the Stack When vector variable goes out of scope: – destructor is called automatically to deallocate the array of elements – the bookkeeping ( sz and elem ), which were on the stack, will automatically be deallocated when the stack frame for that scope is popped Safe! No memory leak 38

39 CSCE 121:509-512 Set 16: Vector and Free Store Deallocation of Vector Declared on the Heap When pointer variable goes out of scope: – the space for the pointer is automatically deallocated when the stack frame for that scope is popped But you are responsible for deallocating the bookkeeping ( sz and elem ) and the array! Note: destructor is automatically called when delete is invoked on a pointer to an object of that class 39

40 CSCE 121:509-512 Set 16: Vector and Free Store Managing a Vector on the Stack vs. Heap Vector on Stack void f() { vector v(5); v.set(0,10); cout << v.get(0); } Vector on Heap void f() { vector* pv = new vector(5); pv->set(0,10); cout get(0); delete pv; } // delete pv automatically calls // destructor, which frees array, // then delete frees sz and elem 40

41 CSCE 121:509-512 Set 16: Vector and Free Store void* void* means “pointer to some memory whose type is unknown to the compiler” Use void* to transmit an address between pieces of code that do not know each other’s types – example: arguments of a callback function There are no objects of type void : void v; // error void f(); // f returns nothing; does not // return an object of type void 41

42 CSCE 121:509-512 Set 16: Vector and Free Store Assigning to void* Any pointer can be assigned to a void* pointer: int* pi = new int; double* pd = new double[10]; void* pv1 = pi; pv1 = pd; 42

43 CSCE 121:509-512 Set 16: Vector and Free Store Using void* Most operations on pointers are forbidden on void* pointers: – cannot dereference, cannot subscript, cannot increment, no implicit conversions Copying (assignment), however, is allowed – that’s what it is for To use what a void* pointer points to, we must explicitly tell the compiler what type of object it points to, using static_cast – use static_cast only when absolutely necessary! 43

44 CSCE 121:509-512 Set 16: Vector and Free Store Code Examples with void* void f(void* pv) { void* pv2 = pv; // OK – copying double* pd = pv; // error – implicit conversion *pv = 7; // error – dereference pv[2] = 9; // error – subscript pv++; // error – increment int* pi = static_cast (pv); // OK – // explicit conversion //... can access the memory via pi } 44

45 CSCE 121:509-512 Set 16: Vector and Free Store void* and FLTK Callbacks void* is the closest C++ has to a plain machine address Some system facilities require a void* Remember FLTK callbacks? The parameters were of type Address, which is just a synonym for void* : typedef void* Address; void Lines_window::cb_next(Address,Address); 45

46 CSCE 121:509-512 Set 16: Vector and Free Store Acknowledgments Photo on slide 1: by mekuria getinet, licensed under CC BY2.0 Photo on slide 1mekuria getinetCC BY2.0 Core C++: A Software Engineering Approach, Victor Shtern, Prentice Hall, 2000 Slides are based on those for the textbook: http://www.stroustrup.com/Programming/17_free_store.ppt 46


Download ppt "CSCE 121:509-512 Introduction to Program Design and Concepts, Honors Dr. J. Michael Moore Spring 2015 Set 16: Vector and Free Store CSCE 121-200: Set 16:"

Similar presentations


Ads by Google