Memory Management
Total Page:16
File Type:pdf, Size:1020Kb
The memory int • • Address • 1036 0 0 1 0 0 1 0 0 1 1 1 0 0 0 1 0 1 0 1 0 0 1 0 0 1 0 1 0 0 0 1 0 1040 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0190 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1044 0 0 1 0 0 1 0 0 0 1 1 1 0 0 0 0 0 1 1 0 1 0 0 1 0 1 0 1 0 0 0 0 Memory management 1048 1 0 0 1 0 0 1 1 0 0 0 byte0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1052 0 1 0 0 1 0 1 0 1 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 1056 0 0 1 0 0 1 0 1 1 1 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1060 1 1 0 1H1 0 1 0 0 0 0 1e0 0 1 0 0 0 0 0l1 0 0 0 1 0 0 1l0 0 1 0 1064 0 1 0 1o0 1 0 1 0 1 0 0 0 1 1 1 1 1 0 1w0 0 0 0 0 0 0 0o1 0 0 1 1068 0 0 1 0r1 0 0 0 1 0 0 1l0 1 1 0 0 0 1 0d0 1 0 0 0 1 0 1 0 1 1 0 1072 0 1 1 1 0 0 1 1 0 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1076 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 000 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1080 0 0 1 0 1 1 0 1 0 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0 1084 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 • Jordi Cortadella and Jordi Petit • • Department of Computer Science string (“Hello world”) Memory management © Dept. CS, UPC 2 Pointers Pointers Memory • Given a type T, T* is another type called “pointer to T”. • It holds the memory address of an object of type T. Address of a variable (reference operator &): i int i; j • Examples: int* pi = &i; // &i means: “the address of i” int* pi; pi myClass* pC; • Access to the variable (dereference operator *) int j = *pi; • Pointers are often used to manage the memory space // j gets the value of the variable pointed by pi of dynamic data structures. • Null pointer (points to nowhere; useful for initialization) • In some cases, it might be convenient to obtain the address of a variable during runtime. int* pi = nullptr; Memory management © Dept. CS, UPC 3 Memory management © Dept. CS, UPC 4 Dynamic Object Creation/Destruction Access to members through a pointer • The new operator returns a pointer to a newly created object: The members of a class can be accessed through a pointer to the class via the -> operator: myClass* c = new myClass( ); myClass* c = new myClass{ }; // C++11 myClass* c = new myClass; vector<int>* vp = new vector<int> (100); … vp->push_back(5); • The delete operator destroys an object through a … pointer (deallocates the memory space associated to int n = vp->size(); the object): delete c; // c must be a pointer Memory management © Dept. CS, UPC 5 Memory management © Dept. CS, UPC 6 Allocating/deallocating arrays References new and delete can also create/destroy arrays of objects • A reference defines a new name for an existing value (a synonym). c myClass[0] // c is a pointer to an myClass[1] // array of objects • References are not pointers, although they are myClass[2] myClass* c = new myClass[10]; usually implemented as pointers (memory myClass[3] // c[i] refers to one of the references). myClass[4] // elements of the array myClass[5] c[i].some_method_of_myClass(); myClass[6] • Typical uses: myClass[7] // deallocating the array delete [] c; – Avoiding copies (e.g., parameter passing) myClass[8] myClass[9] – Aliasing long names – Range for loops Memory management © Dept. CS, UPC 7 Memory management © Dept. CS, UPC 8 References: examples Pointers vs. references • A pointer holds the memory address of a variable. A auto & r = x[getIndex(a, b)].val; reference is an alias (another name) for an existing variable. ... r.defineValue(n); // avoids a long name for r ... • In practice, references are implemented as pointers. // avoids a copy of a large data structure • A pointer can be re-assigned any number of times, whereas bigVector & V = myMatrix.getRow(i); a reference can only be assigned at initialization. ... • Pointers can be NULL. References always refer to an object. // An alternative for the following loop: // for (int i =0; i < a.size(); ++i) ++a[i]; • You can have pointers to pointers. You cannot have references to references. for (auto x: arr) ++x; // does not work (why?) for (auto & x: arr) ++x; // it works! • You can use pointer arithmetic (e.g., &object+3). Reference arithmetic does not exist. Memory management © Dept. CS, UPC 9 Memory management © Dept. CS, UPC 10 The Vector class • The natural replacement of C-style arrays. • Main advantages: – It can dynamically grow and shrink. The Vector class – It is a template class (can handle any type T) – No need to take care of the allocated memory. – Data is allocated in a contiguous memory area. (an approximation to the STL vector class) • We will implement a Vector class, a simplified version of STL’s vector. • Based on Weiss’ book (4th edition), see Chapter 3.4. Memory management © Dept. CS, UPC 12 The Vector class The Vector class template <typename Object> template <typename Object> theSize: 3 class Vector { class Vector { theCapacity: 5 a[0] public: public: objects: a[1] … … a[2] private: private: … int theSize; }; int theCapacity; Object* objects; a pointer ! • What is a class template? }; – A generic abstract class that can handle various datatypes. – The template parameters determine the genericity of the class. • A Vector may allocate more memory than needed (size vs. capacity). • Example of declarations: • The memory must be reallocated when there is no enough capacity in the storage area. – Vector<int> V; – Vector<polygon> Vp; • The pointer stores the base memory address (location of objects[0]). Pointers – Vector<Vector<double>> M; can be used to allocate/free memory blocks via new/delete operators. Memory management © Dept. CS, UPC 13 Memory management © Dept. CS, UPC 14 The Vector class Memory management theSize: a[0] 3 theSize: 4 a[0] B’s A’s C’s A C B theCapacity: 5 a[1] theCapacity: 5 a[1] storage storage storage objects: a[2] objects: a[2] a[3] After resizing B’s storage (e.g., B.push_back(…)) a.push_back(…) A’s B’s C’s A C B storage storage storage a.push_back(…) • Data structures usually have a descriptor (fixed size) and a storage area (variable size). theSize: 5 a[0] Memory blocks cannot always be resized. They need to be reallocated and initialized theCapacity: 5 a[1] with the old block. After that, the old block can be freed. objects: a[2] a[3] • Programmers do not have to take care of memory allocation, but it is convenient to a.push_back(…) a[4] know the basics of memory management. • Beware of memory leaks, fragmentation, … Memory management © Dept. CS, UPC 15 Memory management © Dept. CS, UPC 16 The Vector class The Vector class public: public: // Returns the size of the vector // Returns a const ref to the last element theSize: 3 int size() const const Object& back() const theSize: 3 theCapacity: 5 a[0] { return objects[theSize – 1]; } { return theSize; } theCapacity: 5 a[0] objects: a[1] objects: a[1] a[2] // Returns a ref to the i-th element // Is the vector empty? a[2] bool empty() const Object& operator[](int i) { return size() == 0; } { return objects[i]; } // Adds an element to the back of the vector // Returns a const ref to the i-th element void push_back(const Object & x) { const Object& operator[](int i) const if (theSize == theCapacity) reserve(2*theCapacity + 1); { return objects[i]; } objects[theSize++] = x; } // Modifies the size of the vector (destroying // elements in case of shrinking) // Removes the last element of the array void resize(int newSize) { void pop_back() if (newSize > theCapacity) reserve(newSize); { theSize--; } see later theSize = newSize; } Memory management © Dept. CS, UPC 17 Memory management © Dept. CS, UPC 18 The Vector class Constructors, copies, assignments // Reserves space (to increase capacity) void reserve(int newCapacity) { if (newCapacity <= theCapacity) return; MyClass a, b; // Constructor is used // Allocate the new memory block MyClass c = a; // Copy constructor is used Object* newArray = new Object[newCapacity]; b = c; // Assignment operator is used // Copy the old memory block for (int k = 0; k < theSize; ++k) newArray[k] = objects[k]; // Copy constructor is used when passing // the argument to a function (or returning theCapacity = newCapacity; // the value from a function) // Swap pointers and free old memory block std::swap(objects, newArray); theSize: void foo(Myclass x); delete [] newArray; 3 theCapacity: a[0] } 5 … objects: a[1] foo(c); // Copy constructor is used a[2] Memory management © Dept.