Title: EE441 Data Structures Chapter VII Classes and Dynamic Memory
1EE441 Data StructuresChapter VIIClasses and
Dynamic Memory
- Özgür B. Akan
- Department of Electrical Electronics
Engineering - Middle East Technical University
- akan_at_eee.metu.edu.tr
- www.eee.metu.edu.tr/akan
2Static Memory Allocation
- Usually when a program block is activated, i.e.,
procedure called, object created etc., memory is
allocated for its data items - Local variables, input parameters (or their
addresses) are copied into the local data areas - Upon exit, the local data areas are freed,
i.e., returned to system memory manager - Global data areas are allocated upon start of
execution - The size to be allocated is determined during
compile time (e.g., 1 word for short int, 2 words
for long int, as much as required for array size,
etc.)
This is STATIC memory allocation!
3Dynamic Memory Allocation
- Alternatively, dynamic allocation allows the
program to obtain memory from the system memory
manager and give back to it as required during
execution. - Memory allocation operator New
- A common constructor function for all classes
4Memory Allocation Operator
- e.g. T p // declare p as a pointer to
- // objects that belong to class T
- pnew T // p gets the address of memory
- // allocated to a newly created and
- // unnamed object of class T
- e.g. int p1 // p1 points to 1-word integers
- long p2 // p2 points to 2-word integers
- p1 new int // allocate space for an unnamed
- // 1-word integer and put its address in p1
- p2 new long
- T yeniT(value) // a named object created
using - // constructor function
5Memory Allocation Operator
- By default, the content in memory have no initial
value - An initial value may be assigned to the newly
created object by providing the value as a
parameter when the operator is used - e.g. p new T(value) // constructor for object
p - p2 new long(250000) // constructor for
object p2 - Dynamically allocated memory can only be accessed
through pointers
6Dynamic Array Allocation
- e.g. allocating space for an array whose size is
not known until execution time - pnew Tn // allocate an unnamed array of n
- // items of class T
- Note an array allocated this way cannot specify
initial data - Note if the new constructor fails to obtain
sufficient memory, the returned value is null - e.g. long p
- pnew long50 // allocate an array of 50 long
integers - if (pNULL)
-
- cerrltlt "Memory allocation failed!ltlt endl
- exit(1) // terminate the program
-
7Memory Deallocation
- Unused memory should be returned to system memory
manager for future use. - Memory deallocation operator delete
- e.g. T p, q
- p new T
- q new Tn
- delete p // deallocates object currently
// pointed by p - delete q // deallocates entire array
// currently pointed by q - All dynamic memory must be freed if it is not
needed anymore
8Allocation of Object Data
- We know that objects are created (memory
allocated) by using the constructor function - e.g. we used
- Rectangle t(2.5,5)
- to construct (i.e., allocate memory for) and
object called t of class Rectangle - or we used
- Date day1(10,29,23)
- Date day3(09/28/04)
- to create objects day1 and day3 that belong to
class Date - How can we return space reserved in this way back
to system memory manager??
9Deallocation of Objects
- Answer 1) Upon returning from the block in which
the object was created, memory is automatically
freed. - Answer 2) A destructor function that
de-allocates memory can also be defined together
with a constructor function - e.g. class Date
-
- private
- int month, day, year
- public
- Date(int m1, int d1, int y0)
- Date(char dstr)
- Date(void) // destructor function
- // never has parameters
- // never has a return type
-
10Destructor Function (example)
- e.g. class Rectangle
-
- private
- float length, width
- public
- Rectangle(float l0, float w0)
- float GetLength(void) const
-
- Rectangle(void) // destructor function
-
11Destructor Function
- Now, whenever an object of class Date is created,
memory is allocated for it. - That memory space is freed (object destructed)
- Case 1) upon exiting from the block in which the
object was locally created (static storage), - e.g.
- Date d1
-
- // out of scope
- or
- Case 2) whenever an explicit delete operation
referring to that object is executed (dynamic
storage). - e.g. Date p
- p new Date
-
- delete p
12Destructor Function
- The destructor function is automatically called
by the compiler when an object is deleted in
cases 1 2. - The destructor function is defined by the user,
and may - clean up, i.e., delete, all dynamic memory
created by the object being deleted - give messages, close I/O streams, remove
temporary files, refresh windows etc.
13Classes with Dynamic Memory
- e.g. template ltclass Tgt
- class DynamicClass
-
- private
- T member1
- T member2
- public
- DynamicClass(const T m1, const T m2) //
constructor to initialize // member
data - // Another constructor that creates a copy of
the input object - // (copy constructor)
- DynamicClass(const DynamicClassltTgt obj)
- // destructor
- DynamicClass(void)
- // assignment operator defined for this class
(Operator Overloading) - DynamicClass ltTgt operator(const
DynamicClassltTgt rhs) -
14Classes with Dynamic Memory
- // class implementation
- // implementation of the initializing constructor
- template ltclass Tgt
- DynamicClassltTgtDynamicClass(const T m1, const
T m2) -
- member1m1 // initialize static member
- member2 new T(m2) // allocate dynamic memory
and initialize it with value m2
15Classes with Dynamic Memory
- The following statements define a static variable
staticObj and a pointer variable dynamicObj. - The staticObj has parameters 1 and 100 that
initialize the data members
e.g. DynamicClassltintgt staticObj(1,100)
creates
16Classes with Dynamic Memory
- In the following, the object dynamicObj points to
an object created by the new operator. - 2 and 200 are supplied as parameters to the
constructor
e.g. DynamicClassltintgt dynamicObj //
pointer variable dynamicObj new
DynamicClassltintgt(2,200) // allocate an object
creates
Unnamed Object of class DynamicClassltintgt
200
dynamicObj
Member 1
Member 2
2
17Classes with Dynamic Memory
- e.g. // a different function that creates an
object of // DynamicClass
with integer data - void funct(int m1, int m2)
-
- DynamicClassltintgt obj(m1,m2)
-
- Whenever funct is called, an object locally named
obj will be created - upon returning from funct, obj is destroyed,
but dynamically allocated memory is not
de-allocated!!!
i.e. funct called
After return from funct
Not returned to system memory manager
obj
18Classes with Dynamic Memory
- Dynamic data still remains in the system memory.
- For effective memory management, we need to
deallocate the dynamic data within the object at
the same time the object being destroyed. - We need to reverse the action of the constructor,
which originally allocated the dynamic data. - The C language provides a member function,
called the destructor, which is called by the
compiler when an object is destroyed. - For DynamicClass, the destructor has the
declaration - DynamicClass(void)
19Classes with Dynamic Memory
- The character "" represents "complement", so
DynamicClass is the complement of a constructor.
- A destructor never has a parameter or a return
type. - For our sample class, the destructor is
responsible to deallocate the dynamic data for
member2.
// destructor deallocates memory allocated by
the constructor template ltclass
Tgt DynamicClassltTgtDynamicClass(void) delete
member2
RECALL The destructor is automatically called
whenever object is deleted, i.e., either return
from block in which the object was created, or
when the object is explicitly deleted!!!
20Classes with Dynamic Memory
- e.g. void funct(int m1, int m2)
-
- DynamicClassltintgt Obj(m1,m2) //constructor
for Obj(3,300) - ? // destructor for Obj
- void main(void)
-
- DynamicClassltintgt Obj_1(1,100), Obj_2
- // constructor for unnamed object pointed by
Obj_2 - Obj_2 new DynamicClassltintgt(2,200)
- funct(3,300)
- delete Obj_2 // destructor for unnamed object
pointed by Obj_2 - ? // destructor for Obj_1
21Assignment and Initialization
- Assignment and initialization are basic
operations that apply to any object - The assignment YX causes a bitwise-copy of the
data from object X to the data in object Y - Initialization creates a new object that is a
copy of another object. - The operations are illustrated with objects X and
Y
e.g. // initialization DynamicClassltintgt
X(20,50), YX // creates DynamicClass objects X
and Y // data in Y is initialized by data in X
// with assignment YX data in Y is overwritten
by data in X
22Assignment and Initialization
e.g. // initialization DynamicClassltintgt
A(2,3), B(7,9) // creates DynamicClass objects A
and B BA // B is overwritten by data in A
B
A
B (after BA)
Special consideration must be taken with dynamic
memory so that unintended errors are avoided!!!
We must create new methods that handle object
assignment and initialization!
23Assignment Issues
- Solution Overloading the assignment operator
- To implement the assignment operator an
overloaded operator can be defined so that all
private, public and dynamic data are copied
rather than a bitwise copying of data members - // Overloaded assignment operator returns a
reference to the current object - template ltclass Tgt
- DynamicClassltTgt DynamicClassltTgtoperator
(const DynamicClassltTgt rhs) - // copy static data member from rhs to the
current object - member1rhs.member1
- // content of the dynamic memory must be same as
that rhs member2rhs.member2 - return this // reserved word this is used to
return the object for which the current - // assignment operator has been invoked
-
this is a pointer, this is the object
this-gtmember1 is the member1 of current
object this-gtmember2 is the pointer inside the
current object
24Copy Constructor
- In order to properly handle classes that allocate
dynamic memory, C provides the copy constructor
to allocate dynamic memory for the new object and
initialize its data values - The copy constructor is a member function that is
declared with the class name and a single
parameter. - Because it is a constructor, it does not have a
return value - The copy constructor is used when a new object is
created and initialized to the values in another
existing object. - The parameter in the copy constructor must be
passed by reference, and it must be const, i.e.,
read only.
25Initialization with Copy Constructor
- Object initialization is an operation that
creates a new object that is a copy of another
object. - Like assignment, when the object has dynamic
data, the operation requires a specific member
function, called the copy constructor - Hence, to solve the problem with YX
(initialization), we need to implement the copy
constructor - // implementing the copy constructor
- template ltclass Tgt
- DynamicClassltTgtDynamicClass(const
DynamicClassltTgt obj) - // copy static data member from obj to the
current object - member1obj.member1
- // allocate dynamic memory and initialize it
properly - member2 new T(obj.member2)
-
26Copy Constructor
- e.g.
- template ltclass Tgt
- DynamicClassltintgt Demo(DynamicClassltTgt one,
DynamicClassltTgt two, T m) -
- DynamicClassltTgt obj(m,m) // calling
constructor - return obj // copy constructor called for
temporary return object, // which is a copy
of obj - // temporary objects m and one are destroyed
upon return - void main()
-
- DynamicClassltintgt A(3,5), BA, C(0,0)
- CDemo(A,B,7)
-
Calls copy constructor
two simply refers to object B
Upon return from Demo, overloaded assignment used
to copy obj into C
The call uses the copy constructor, creates the
value one parameter as a copy of A
27Assignment and Initizalition
- Despite their similarity, assignment and
initialization are clearly different operations. - Assignment is done when the object on the
left-handside already exists. - In the case of initialization, a new object is
created by copying data from an existing object.