Dynamic storage P.J. Drongowski 19 October 2004 Kinds of storage (variables) [Thanks Alva!] * Global variables - Are outside scope of { } - Lifetime is of a global variable is the duration of program execution - initially binary 0 (whatever that means). - scope is lexical from declaration to end of file. * Local variables - Are inside the scope of { } - Lifetime of a local variable is the duration of the function containing the block. - Initially a local variable has unpredictable contents - Local variables must be initialized by the function or block - Scope of a local variable is from its declaration to the end of the block containing it, including all sub-blocks. * Dynamic storage - Anonymous (no program-level name) - Is allocated by the operator new, e.g., new int[20] - Storage is allocated from a heap (i.e., a pool of free storage) - Is accessible from any function possessing a pointer to the variable - Lifetime of dynamic storage is from allocation until it is explicitly deallocated via the delete operator The new operator new Type Allocate object of Type Exception on failure new(nothrow) Type Allocate object of Type Return NUL on failure new Type[ ... ] Allocate array of Type Exception on failure new(nothrow) Type[ ... ] Allocate array of Type Return NULL on failure The delete operator delete pointer Deallocate storage for object delete [] array_pointer Deallocate storage for array of objects Example: Just an integer int *ptr_to_int ; ptr_to_int = new int ; ... delete int ; Example: Dynamic array int *ptr_to_array ; ... ptr_to_array = new int[20] ; ... v = ptr_to_array[i] ; ... delete [] ptr_to_array ; Example: Catching allocation exception try { ptr_to_array = new int[20] ; } catch (bad_alloc ex) { cerr << "*error* Allocation failed" << endl ; exit( 1 ) ; } Memory leaks * You *must* deallocate storage when done with it * Just overwriting the pointer value is not enough -- it leaves orphaned storage that cannot be reclaimed * Java programmers beware! + Java handles deallocation of storage + It keeps a reference count for storage blocks + When a new reference is created, it increments the count + When a reference is lost, it decrements the count + The storage block is released when the count reaches zero * Typical C++ practice + Allocate new storage in constructor + Deallocate existing storage in destructor + It's customary to set the pointer to NULL after deallocation + Use assert(ptr != NULL) wherever possible Pointer aliasing * More than one pointer can refer to the same block of storage * Compilers have trouble optimizing code in the presence of aliases Copy constructors * Makes an exact copy of an object * C++ provides a default copy constructor that performs a member-by-member copy * Does the default copy constructor copy dynamically allocated data structures? No! * The programmer must provide a copy constructor for any class that uses dynamic storage * When is a copy constructor called? + An instance of a class (object) is passed by value to a function (Call by value is the default in C++) + An instance of a class is returned from a function call + An instance of a class is initialized to another instance using an initializer + An instance of a class is provided explicitly as a single argument to the constructor * The copy constructor takes one parameter -- a const reference to the object to be copied -- and turns the current instance (this) into an exact copy of the parameter object * The copy constructor must copy over certain members and must allocate and build an exact copy of any dynamic data structures Overloaded assignment operator * Usually, an overloaded assignment operator is defined along with a copy constructor; Otherwise, C++ will create a default assignment operator the performs a member-by-member copy * The prototype (signature) syntax is: const & operator=(const & ) ; where means and is a reference to the object which is being copied * The definition has the form: const & ::operator=(const & ) { // Make a copy of return *this ; } * The definition must make an exact copy just like the copy constructor Sources: Practical C++ Programming, Steve Oualline, O'Reilly, 2003 C++ Pocket Reference, Kyle Loudon, O'Reilly, 2003 ADTs, Data Structures and Problem Solving with C++, Larry Nyhoff, Pearson Prentice Hall, 2005