Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

Dynamic Memory Allocation and Arrays of Objects in Computing and Statistical Data Analysis, Slides of Computational and Statistical Data Analysis

This document from lecture 6 of the computing and statistical data analysis course covers dynamic memory allocation using the new operator, dynamic arrays, memory leaks, dangling pointers, operator overloading, static member functions, and class templates. It also includes examples using the twovector class.

Typology: Slides

2011/2012

Uploaded on 03/08/2012

leyllin
leyllin 🇬🇧

4.3

(15)

22 documents

1 / 23

Toggle sidebar

Partial preview of the text

Download Dynamic Memory Allocation and Arrays of Objects in Computing and Statistical Data Analysis and more Slides Computational and Statistical Data Analysis in PDF only on Docsity! Computing and Statistical Data Analysis Lecture 6 Arrays of objects Memory allocation: static, automatic and dynamic Memory leaks and dangling pointers Operator overloading Static member functions digression on destructors, copy constructors Class templates G. Cowan / RHUL 1 Computing and Statistical Data Analysis / Lecture 6 Dynamic arrays An array’s name is a pointer to its first element. We can create a “dynamic array” using the new operator: double* array; int len; cout << "Enter array length" << endl; cin >> len; // array length set at run time array = new double[len]; ... When we’re done (e.g. at end of function where it’s used), we need to delete the array: delete [] array; G. Cowan / RHUL 2 Computing and Statistical Data Analysis / Lecture 6 The stack When a variable is created by a “usual declaration”, i.e., without new, memory is allocated on the “stack”. When the variable goes out of scope, its memory is automatically deallocated (“popped off the stack”). ... { int i = 3; // memory for i and obj MyObject obj; // allocated on the stack ... } // i and obj go out of scope, // memory freed G. Cowan / RHUL 5 Computing and Statistical Data Analysis / Lecture 6 The heap To allocate memory dynamically, we first create a pointer, e.g., MyClass* ptr; ptr itself is a variable on the stack. Then we create the object: ptr = new MyClass( constructor args ); This creates the object (pointed to by ptr) from a pool of memory called the “heap” (or “free store”). When the object goes out of scope, ptr is deleted from the stack, but the memory for the object itself remains allocated in the heap: { MyClass* ptr = new MyClass(); // creates object ... } // ptr goes out of scope here -- memory leak! This is called a memory leak. Eventually all of the memory available will be used up and the program will crash. G. Cowan / RHUL 6 Computing and Statistical Data Analysis / Lecture 6 Deleting objects To prevent the memory leak, we need to deallocate the object’s memory before it goes out of scope: { MyClass* ptr = new MyClass(); // creates an object MyClass* a = new MyClass[n]; // array of objects ... delete ptr; // deletes the object pointed to by ptr delete [] a; // brackets needed for array of objects } For every new, there should be a delete. For every new with brackets [], there should be a delete [] . This deallocates the object’s memory. (Note that the pointer to the object still exists until it goes out of scope.) G. Cowan / RHUL 7 Computing and Statistical Data Analysis / Lecture 6 Operator overloading Suppose we have two TwoVector objects and we want to add them. We could write an add member function: TwoVector TwoVector::add(TwoVector& v){ double cx = this->m_x + v.x(); double cy = this->m_y + v.y(); TwoVector c(cx, cy); return c; } To use this function we would write, e.g., TwoVector u = a.add(b); It would be much easier if would could simply use a+b, but to do this we need to define the + operator to work on TwoVectors. This is called operator overloading. It can make manipulation of the objects more intuitive. G. Cowan / RHUL 10 Computing and Statistical Data Analysis / Lecture 6 Overloading an operator We can overload operators either as member or non-member functions. For member functions, we include in the class declaration: class TwoVector { public: ... TwoVector operator+ (const TwoVector&); TwoVector operator- (const TwoVector&); ... Instead of the function name we put the keyword operator followed by the operator being overloaded. When we say a+b, a calls the function and b is the argument. The argument is passed by reference (quicker) and the declaration uses const to protect its value from being changed. G. Cowan / RHUL 11 Computing and Statistical Data Analysis / Lecture 6 Defining an overloaded operator We define the overloaded operator along with the other member functions, e.g., in TwoVector.cc: TwoVector TwoVector::operator+ (const TwoVector& b) { double cx = this->m_x + b.x(); double cy = this->m_y + b.y(); TwoVector c(cx, cy); return c; } The function adds the x and y components of the object that called the function to those of the argument. It then returns an object with the summed x and y components. Recall we declared x() and y(), as const. We did this so that when we pass a TwoVector argument as const, we’re still able to use these functions, which don’t change the object’s state. G. Cowan / RHUL 12 Computing and Statistical Data Analysis / Lecture 6 Restrictions on operator overloading You can only overload C++’s existing operators: Unary: + - * & ~ ! ++ -- -> ->* Binary: + - * / & ^ & | << >> += -= *= /= %= ^= &= |= <<= >>= < <= > >= == != && || , [] () new new[] delete delete[] Operator precedence stays same as in original. Too bad -- cannot replace pow function with ** since this isn’t allowed, and if we used ^ the precedence would be very low. Recommendation is only to overload operators if this leads to more intuitive code. Remember you can still do it all with functions. You cannot overload: . .* ?: :: G. Cowan / RHUL 15 Computing and Statistical Data Analysis / Lecture 6 A different “static”: static members Sometimes it is useful to have a data member or member function associated not with individual objects but with the class as a whole. An example is a variable that counts the number of objects of a class that have been created. These are called static member functions/variables (yet another use of the word static -- better would be “class-specific”). To declare: class TwoVector { public: ... static int totalTwoVecs(); private: static int m_counter; ... }; G. Cowan / RHUL 16 Computing and Statistical Data Analysis / Lecture 6 Static members, continued Then in TwoVector.cc (note here no keyword static): int TwoVector::m_counter = 0; // initialize TwoVector::TwoVector(double x, double y){ m_x = x; m_y = y; m_counter++; // in all constructors } int TwoVector::totalTwoVecs() { return m_counter; } Now we can count our TwoVectors. Note the function is called with class-name:: and then the function name. It is connected to the class, not to any given object of the class: TwoVector a, b, c; int vTot = TwoVector::totalTwoVecs(); cout << vTot << endl; // prints 3 G. Cowan / RHUL 17 Computing and Statistical Data Analysis / Lecture 6 Class templates We defined the TwoVector class using double variables. But in some applications we might want to use float. We could cut/paste to create a TwoVector class based on floats (very bad idea -- think about code maintenance). Better solution is to create a class template, and from this we create the desired classes. template <class T> // T stands for a type class TwoVector { public: TwoVector(T, T); // put T where before we T x(); // had double T y(); ... }; G. Cowan / RHUL 20 Computing and Statistical Data Analysis / Lecture 6 Defining class templates To define the class’s member functions we now have, e.g., template <class T> TwoVector<T>::TwoVector(T x, T y){ m_x = x; m_y = y; m_counter++; } template <class T> T TwoVector<T>::x(){ return m_x; } template <class T> void TwoVector<T>::setX(T x){ m_x = x; } With templates, class declaration must be in same file as function definitions (put everything in TwoVector.h). G. Cowan / RHUL 21 Computing and Statistical Data Analysis / Lecture 6 Using class templates To use a class template, insert the desired argument: TwoVector<double> dVec; // creates double version TwoVector<float> fVec; // creates float version TwoVector is no longer a class, it’s only a template for classes. TwoVector<double> and TwoVector<float> are classes (sometimes called “template classes”, since they were made from class templates). Class templates are particularly useful for container classes, such as vectors, stacks, linked lists, queues, etc. We will see this later in the Standard Template Library (STL). G. Cowan / RHUL 22 Computing and Statistical Data Analysis / Lecture 6
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved