<Previous Lesson

Introduction to Programming

Next Lesson>


Lesson 39


51) Pointers
52) References
53) Call by Value
54) Call by Reference
55) Dynamic Memory Allocation
56) Assignment and Initialization
57) Copy constructor
58) Example
59) Rules for Using Dynamic Memory Allocation
60) Usage of Copy Constructor
61) Summary
62) Exercise

In this lecture, we will review the concepts like pointers, references and memory
allocation, discussed in the previous lectures. The review of these topics will help
enhance our understanding of the programming. Let’s discuss these topics one by one.



Pointer is a special type of variable that contains a memory address. It is not a variable
that contains a value, rather an address of the memory that is contained inside a pointer
In C++ language, variables can be without type. Either we can have a void pointer or
these can be typed. So we can have a pointer to an integer, a pointer to a character and a
pointer to a float etc. Now we have a user-defined data type, which we call classes, so we
can have pointers to classes.
While talking about pointers, we actually refer to pointing to an area in memory. A
pointer to an integer, points to a location opted by an integer in memory. If there is an
Page 498
array of integers in the memory, we can still use a pointer to point to the beginning of the
array. This is a simple manipulation. To have the address of a memory location, we use &
sign. The ‘&’ sign is also used in references. So we have to be very cautious while
making its use. To further overcome this ambiguity, we will now recapture the concept of


A reference can be considered as a special type of pointer as it also contains memory
address. There are some differences between pointers and references. Pointers may point
to nothing while references always have to point to something. A reference is like an alias
for an object or a variable. The references should be used when we are implementing the
call by reference. This helps us make our syntax easier as we can implement the call by
reference with out using the * operator.

Call by Value

Whenever we call a function and pass an argument, an object or variable to the function,
then by the default rule of C and C++, it is a call by value. It means that the original data
remains at its place and a temporary copy of it is made and passed to the function.
Whatever the function does with this copy, the original value, in the calling function,
remains intact. This is a call by value.

Call by Reference

If we want a function to change something in the original object variable or whatever,
that variable or object by reference would be passed. To do this, we don’t make
temporary copy of that object or variable. Rather, the address of the variable is sent.
When the function manipulates it, the original object will be manipulated, effecting
change in its values. The use of call by reference is also important for the sake of
efficiency. If we have a large object, sending of its copy will be something insufficient. It
will occupy a large space on the stack. Here, we can use call by reference instead of call
by value only for efficiency while we need not to change the original object. For this, we
use a keyword const that means that a const (constant) reference is being passed. The
function can use its values but cannot change it.
Now we come to the dynamic memory allocation.

Dynamic Memory Allocation

In C language, we have a method to allocate dynamic memory. In it, while executing the
program, we allocate some memory from the free store (heap) according to our need, use
it and after using, send it back to the free store. This, dynamic memory allocation, is a
very common function in programming. While writing C++ language, it was decided that
it should not be implemented by a function call. There should be native operators,
supposed to be very efficient. These operators are new and delete. We allocate memory
with the new operator from the free store. It returns a pointer. For example, if we say p is
a pointer to an integer, the statement will be written as
int *p ;
Page 499
Now we write
p = new int ;
This statement performs the task in the way that it gets memory for an integer from the
free store. There is no variable name for that memory location but the address of this
location is stored in the pointer p. Now by using the syntax *p (which means whatever p
points to), we can manipulate that integer value. We can also write to and read from that
location. This memory allocation is done during the execution of the program. Whenever
we allocate memory with the new operator, it is our responsibility to de-allocate this
memory after the termination of the program. To do this de-allocation, we have an
operator delete. To de-allocate the memory, allocated with p = new int ; we will write
delete (p) ;
It will not delete the p rather, it will send the memory gotten and pointed by p back to the
free store.
Same thing happens when we try to allocate more than a simple variable i.e. when we are
trying to allocate arrays. When we use new operator to allocate a space for an array, we
tell the size of the array in square brackets (i.e. []). We can write it like
p = new int [10] ;
This statement says p is pointing to an area of memory having the capability to store 10
integers. So there is an array of 10 integers whereas p is pointing to the beginning point
of the array. Now we can access the elements of the array by manipulating the pointer p.
To make the memory allocated for an array free, the syntax is a little bit different.
Whenever, we allocate an array then to free it we write
delete [] p ;
This will free the array that is pointed by p. In this case, the space of 10 integers that was
pointed by p, will be de-allocated despite the fact that we write empty brackets with the
operator. This is due to the fact that C++ internally has the record that how much
memory was allocated while allocating an array. After delete, the pointer points to
nothing. So it’s a free pointer and can be reused.
Now let’s go on and look at a special type of objects. These are the objects with the data
members as the pointers. In the previous lectures, we had discussed the example of a
class Matrix. In that class, we said that it will be a two dimensional matrix while talking
about its size etc. In this example, it will be a generic class besides being a matrix of 3 x
3. Now we want to see the Matrix class defined such a way that the programmer can take
an object of it of any size at any time, say a matrix of 3 x 3, 5 x 5 or 10 x 10. It means
Page 500
that the size of the matrix should be variable. Now we have to bring every thing together
in terms of how we declare and manipulate arrays inside a C++ program.
Whenever we declare an array, we have to mention its size. It is necessary, as otherwise
no memory will be allocated, it’s about the static memory allocation. In it, we declare like
that it will be a two dimensional array of m rows and n columns. The compiler will
allocate a memory for this array at the start of the program. Now we are talking about that
at the compilation time, we don’t know the size of the array. We want to allocate an array
of the required size at run time. When the constructor of the class is called, the memory
required by that object should be allocated at that time. For example, in case of Matrix
class, we will like to tell the number of rows and columns of the object of the Matrix in
the constructor, so that the constructor could allocate the memory for that object. A
keyword new is used for this purpose. Here, we realize that in case of data member of this
class Matrix, fixed rows and columns cannot be used in the class definition. We cannot
define a two-dimensional array inside the class as it negates the concept of extensibility.
Here, inside the class we define something like int *m; which means m is a pointer to an
integer. It is the data member of the class. In the constructor of the class, we say that it
will take two integer arguments, rows and columns. Whenever we declare an object,
which is an instantiation of the class, the constructor of the class is called. Now in the
constructor of this class we want to allocate memory from the free store equal to the
memory required by m x n (m multiply by n) integers. So if we say a Matrix of 3 rows
and 3 columns then we require memory for 9 (3 * 3) integers. If we say four rows and
five columns then we require a memory for 20 (4 * 5) integers. Now it is very simple,
inside the constructor we will write
m = new int [rows * columns] :
Thus we created a Matrix to which we tell the number of rows and columns, through
variables, during the execution of the program. When we created an object of the class its
constructor is called to which the variable values are passed and by multiplying these
variables (number of rows and columns), we allocate a memory for these integers by the
operator and its address is assigned to m. Thus the object is initialized and the
required memory is available to it. Now we can use it as a two dimensional array and can
put values inside it. Now the class definition of the class Matrix can be written as under.
class Matrix
int *m;
int row, col;
Matrix(int rows, int cols)
m = new int[rows * cols];
Page 501
There is a requirement that if the constructor of a class allocates the memory, it is
necessary to write a destructor of that class. We have to provide a destructor for that
class, so that when that object ceases to exist, the memory allocated by the constructor, is
returned to the free store. It is critically important. Otherwise, when the object is
destroyed, there will be an unreferenced block of memory. It cannot be used by our
program or by any other program. It’s a memory leak that should be avoided. So
whenever we have a class in which the constructor allocates dynamic memory, it is
necessary to provide a destructor that frees the memory. Freeing the memory is an easy
process. We have no need to remember that how many rows and columns were used to
allocate the memory. We simply use the delete operator with empty brackets and the
pointer that points to the allocated memory. We write this as follows
delete [] m ;
This statement frees the allocated memory (whatever its size is) that is being pointed by

Assignment and Initialization

Let us discuss the assignment and initialization. We do initialization as
int i = 0 ;
This is declaring an integer and initializing it. The second way to do this is
int i ;
i = 0 ;
This has the same effect as the first statement but the behavior is different. At first, a
space is allocated for i before assigning a value to it..
The same applies whenever we create an object. We can either create an object, initialize
it at the creation time that means constructor is being called, or we can create an object
and then assigns values to its data members later. This is usually done either by set
functions or with the assignment statements. Here the thing to differentiate is that if we
have two objects of a class, say Matrix, m1 and m2. We have, in some way, created m1,
its rows and columns have been allocated, and values have been put in these rows and
columns. Now somewhere in the program, if we write
m2 = m1 ;
It is an assignment statement. If we have not defined the overloaded operator for
assignment, the default assignment of C will be carried out. The default assignment is a
member-to-member assignment. Now let’s again look at the construct for the Matrix
class. In it, we have only one data member i.e. a pointer to an integer. We have written int
*m ;
in the class definition. So in m1, there is a pointer to an integer but m1 is a fully
Page 502
qualified developed object. It is, let’s say, a 5 x 5 matrix and has values for its entities.
Now when we write
m2 = m1 ;
has also a pointer m to an integer as its own data member. If we have not written an
overloaded assignment operator for this class, the value of m of the object m1 will be
assigned to m of the object m2. Now we have two objects, having pointer variables that
hold the same address. So these are pointing to the same region in the memory. There
arise many problems with this. Firstly, if we destroy m1, the destructor of m1 is called
and it frees the memory. So the memory being pointed by m of the object m1 has gone
back to the free store. Now what happens to m2? There is a pointer in m2, pointing to the
same memory, which has been sent to the free store by the destructor of m1. The memory
is no longer allocated. It has been sent to the free store. So we have a serious problem.
We don’t want two objects to point to the same region in the memory. Therefore, we
write an assignment operator of our own. This assignment operator is such that whenever
we do some object assignment, it allocates separate memory for one object and copies the
values of the second object into that space. Thus the second object becomes an
independent object. So we have to be careful. Whenever we have a class with a dynamic
memory allocation, there is need for writing an assignment operator for it.

Copy Constructor

Now we will see what a copy constructor is? We have discussed the dangers that a
programmer may face during the process of assigning the objects. The same danger
comes to the scene, when we pass an object like the Matrix class to a function that does
some manipulations with it. Suppose, we have a function that takes an object of a class
Matrix as an argument. The default mechanism of calling a function in C or C++ is call
by value. Now what is the value for this object, being passed to the function? The values
of the data members of the object will be placed on the stack. The function will get a
temporary object, as it is a call by value. The original object remains intact. The values of
data members of that temporary object will be the same as the values in the original
object. Now if it is a simple class, there will be no problem. However, if there is a class
with a pointer as its data member and that pointer has allocated some memory, then the
value of that pointer is copied. This value is passed to the function and not the memory.
Now in the function, we have a temporary object that has a pointer as data member,
pointing to the same memory location as the original object. If we are just reading or
displaying that object, there is no problem with it. If we change the values of the object,
the values in the temporary object get changed. However, when we manipulate the
pointer, it changes the values in the memory of the original object. This change in the
original values is the mechanism of the call by reference and here we have done call by
value. We know that a temporary object is passed to the function. So how we get around
this problem? The way to resolve this problem is to create a complete copy of the object.
We want that in this copy of the object the pointer value must not point to the same
memory location. Rather, it must point to the memory location of its own. So we want to
have a copy constructor. That means a constructor that will create a new object with a full
copy of the other object. This is also known as deep copy as opposed to shallow copy.
Page 503
The shallow copy makes a member-to-member copy of the object without taking care
whether the pointer is a pointer or an ordinary variable. The copy of the ordinary
variables is perfectly valid and legal. But if we make a member copy of a pointer, there
may be the problem in which a new pointer variable is created with the same value,
without creating a new area of memory. Therefore, we have to write something special
that is called copy constructor.
The basic line in the syntax of the copy constructor is that we are trying to create a new
object by passing an object of the same class as the argument. So we should think of a
constructor. For example if we have the class Matrix, its prototype will be as under.
Matrix (Matrix &) ;
The ‘&’ sign shows that a reference of the object of type Matrix will be passed. Now
whenever we write a copy constructor, there is need to be very cautious. We have to
allocate a new memory for that copy. When we go into this copy constructor, at first, it is
determined that how much memory the original object has allocated? Since we pass the
object, so all the queries might have answers. For example, in case of Matrix class, we
can find the number of rows and columns. We create a temporary object inside the
constructor and allocate it a memory. Then the values of memory of the original object
are copied into this memory. Now the pointer of this new object will point to this new
location. As the constructor returns nothing and just creates a new object, so there is no
return statement in the constructor. Thus, this copy constructor is completed. The syntax
of this constructor is given below
Matrix::Matrix ( const Matrix &other )
size = other.size ; // size is a function to
determine the
memory allocated by object
m = new int [size] ;
copyvalues ( m, other ) ;
In this case, it creates a new object that actually creates memory. It does not make the
shallow copy so there is no copy of the pointer value. In fact, the pointer has a new value.
But the values pointed to by this pointer (i.e. the values in the new allocated memory) are
the copy of the values in the memory of the original object, and then this fully
constructed object is returned.
Now we have the facility of copy constructor. With it, we can define new objects based
on the existing objects. This copy constructor is necessary for the objects in which the
memory is allocated dynamically. We can use this copy constructor without causing any
problems. Suppose we have written as
Matrix a (3,3) ;
Page 504
We have defined a constructor that takes two arguments rows and columns, as a matrix
‘initializer’. We allocate memory for these rows and columns and create an object. Then
somewhere, later in the program, We write
Matrix b (a) ;
This statement makes a complete copy of already created object a and a new object b is
created. This new object has its own pointer and own memory allocation. This memory
location is different from the memory allocated inside the matrix a. Now if a dies then b
is still a valid object. So a copy constructor is critically useful. It is used when we want to
create a duplicate copy of an object. It is always used whenever we want to do a call by
value into a function to which an object is being passed, and the object is of a class in
which we have allocated the memory dynamically.


Let’s look at an example to further understand these concepts. We write a class String. It
has a data member c that is a pointer to a character. We write a member function (copy
function) of the class, which can copy values in the character array of the class. There is a
constructor that will allocate a space for the character arrays i.e. string. The starting
address of this array will be stored in data member of the class i.e. in a pointer. We have
not written any copy constructor. Now we want to make two objects of this String class,
say, s1 and s2. We create object s1 and assign a string to it. We write it as
String s1 (“test1”) ;
Now after this we write
String s2 = s1 ;
Thus we create a new object s2. The values of s2 are initialized with the values of s1. As
we have written no copy constructor, C will provide the default copy constructor. Now if
we display the string of s2, it will be the same as of s1. Now use the copy function to
assign new values to the string inside the object s1. So we write
s1.copy(“A new string”) ;
Thus we write a new string in s1. Now again if we display the string of s2 by writing
s2.print ;
We will see that it displays the same value, assigned to s1 in the previous statement. The
reason is that the default copy constructor has done member-to-member copy. It has
copied the value of the character pointer to the pointer of s2 and thus both pointers are
pointing to the same memory location.
Page 505
Now there is need of providing a copy constructor for a class like this. We also have to
provide a destructor as we are doing memory allocation inside the constructor of the
Following is the code of the example in which we provide a copy constructor. We create
an object based on an existing object. The copy constructor creates an object with full
copy of the existing object with its values in a new memory location.
/*This program has a copy constructor and demonstrate the use of it.
We create a new object by passing it an existing object, this calls
the copy constructor and thus creates a complete copy of the passing
object, and has its values in new location of memory.
#include <iostream.h>
#include <stdlib.h>
// class definition
class String
char *c;
// copy function
void copy (char *s)
c = s ;
// getting the length of the string
int length ()const
return strlen(c);
String ();
String (const char *s)
c = new char [ 30 ];
strcpy (c, s);
// copy constructor
String( const String &other );
//display the string
void print()
cout << c << endl ;
Page 506
delete []c ;
// definition of copy constructor
String::String( const String &other )
int length;
length = other.length();
c = new char[length + 1];
strcpy( c, other.c );
main ()
String s1("test1");
cout << "The string of s1 is " ;
String s2(s1);
cout << "The string of s2 is " ;
s1.copy("A new string"); // assign new value to string s1
cout << "The string of s1 is " ;
cout << "The string of s2 is " ;
s2.print(); //s2 has its own previous value
The following is the output of the program which shows the use of copy constructor.
The string of s1 is test1
The string of s2 is test1
The string of s1 is A new string
The string of s2 is test1
The other affected part is the assignment operator itself. We know that there are dangers
in the assignment operators of a class in which memory is being allocated. We cannot
write an assignment operator for such a class blindly. When we write an assignment
operator for such a class, that operator must first look at the fact whether there is selfassignment
being done.
Suppose we have an integer i. We have written as
int i ;
i = 10 ;
Page 507
And down to this we write
i = i ;
There is no problem with it. It is a legal statement. It is complicated if we do such
assignment through pointers. In such a case, pointer is pointing to itself and even it has no
problem. But when we do this with objects that have allocated dynamic memory, the
method of assignment is changed. Let’s take the example of Matrix. We have an object of
Matrix, say m1, which has three rows and three columns. Another object, say m2, has five
rows and five columns. Somewhere in the program we write
m1 = m2 ;
Here m2 is a big object while m1 is a small one. We want to assign the big object to the
smaller one. The assignment operator for this type of class, first de-allocates the memory
reserved by the left-hand side object. It frees this by the delete operator. Then it will
determine the memory required by the object on right hand side. It will get that memory
from the free store by using new operator. When it gets that memory, it will copy the
values and thus the statement m1 = m2; becomes effective. So assignment has a
Now if we say
m1 = m1 ;
We have defined assignment operator. This operator will delete the memory allocated by
(i.e. object on L.H.S.). Now it wants to determine the memory allocated by the object
on the right hand side, which in this case, is the same i.e. m1. Its memory has been
deleted. So here we get a problem. To avoid such problem, whenever we write an
assignment operator, for objects of the class that has done memory allocation. After this,
we do other things.
We have discussed the example in which we create an object of Matrix. We create it
using a copy constructor by giving it another object. The syntax of it we have written as
Matrix m2 (m1) ;
This is the syntax of creating an object based on an existing object. We can write it in the
following fashion.
Matrix m2 = m1 ;
While this statement, we should be very clear that it is not an assignment only. It is also a
construction. So whenever we are using initialization, the assignment operator seems as
equal to operator. But actually assignment operator is not called. Think about it logically
that why assignment operator is not called? The assignment operator is called for the
existing objects. There should be some object on the left-hand side, which will call the
assignment operator. When we have written the declaration line
Matrix m2 = m1 ;
The m2 object has not constructed yet. This object of Matrix does not exist at the time of
writing this statement. So it cannot be calling the assignment function or assignment
operator. This is an example of the use of a copy constructor. Thus, there are two
Page 508
different ways to write it. Remember that whenever we create an object and initialize it in
the declaration line, it calls the copy constructor.
Let’s talk about another danger faced by the programmers when they do not provide copy
constructor. The ordinary constructor is there which allocates memory for the objects of
this class. Suppose we do a call by value to a function. Here, we know that a temporary
copy of the object is made and provided to the function. The function does manipulations
with this copy. When the function returns that temporary copy is destroyed. As no copy
constructor is there, a shallow copy, with values of pointers, is made. The destructor
should be there as we do memory allocation in the class. Now suppose that there is a
destructor for that class. Now when this temporary object destroys its destructor executes
and de-allocates the memory. Now as it was a shallow copy so its pointers were pointing
to the same memory as of the original object. In this way, actually, the memory of the
original object is de-allocated. So the pointer of the original object now points to nothing.
Thus, in the process of function call, we destroyed the original object as it is an invalid
object now. Its pointer is pointing to an unknown memory location. This is a subtle but
very critical. This can be avoided by providing a copy constructor, which actually
constructs a fully formed object with its own memory. That temporary object will go to
the function . When it is destroyed, its destructor will de-allocate this memory. However,
the original object will remain the same.

Rules for Using Dynamic Memory Allocation

Whenever we have a class in which we do dynamic memory allocation, there are some
rules that should be followed.
First, we must define a constructor for it. Otherwise, we will not be able to carry out
dynamic memory allocation. This constructor should be such that it gets memory from
the free store, initializes the object properly, sets the value of the pointer and returns a
fully constructed object.
Secondly, we must write an assignment operator for that class. This assignment operator
should first check the self-assignment and then make a deep copy.. So that a properly
constructed object should be achieved..
Thirdly, as we are doing dynamic memory allocation in the constructor, it is necessary to
provide a destructor. This destructor should free the allocated memory.
These three rules are must to follow.

Usage of Copy Constructor

Let us see where the copy constructors are being used?
First, it is used explicitly at some places, where we write
Matrix m2 (m1) ;
Page 509
This is an explicit call to a copy constructor. Here m1 is being passed by reference. If we
want that there should be no change in m1, then it is necessary to use the key word const
with it to prevent any change in m1. The presence of this key word means that the
constructor will do nothing with the object, being passed to it. The use of copy
constructor in this explicit way is clear.
The second way to use the copy constructor is by writing the declaration line as
Matrix m2 = m1 ;
Here the use of copy constructor is not clear. It is not clear by the statement that copy
constructor is being used. It seems an assignment operator is being used. Be careful that it
is not an assignment operator. It is a copy constructor.
The third use of the copy constructor is calling a function and passing it an object by
value. If we have provided a copy constructor, it will be called automatically and a
complete temporary copy (with memory allocation) of the object is given to the function.
If we do not provide copy constructor, the call by value functions will create problems. In
the function, if we change any value of the object, it will change the value in the original
In function calling, when we do the call by value, the copy constructor is called. On the
other hand, in call by reference, copy constructor is not called and the address of the
original object is passed.


A pointer is a variable that holds memory address. The & operator is used to get the
address of a variable or an object. The & sign is also used as a short hand for a reference.
Whenever we have a & sign in the declaration, it implies a reference. Whenever we have
& sign on right hand side of an assignment operator, it is taken as address of an object.
We can do dynamic memory allocation by using pointers.
In C++ language, we have two very efficient operators provided which are new and
. We use the new operator for obtaining memory from the free store. It returns a
pointer to the allocated memory. We store the value of this pointer in a pointer variable.
In a class, which allocates memory dynamically, there is a data member i.e. a pointer.
When we create an object of the class at run time, it will allocate memory according to
our requirement. So there is no waste of memory and the situations in which we want to
store large data in small memory or vice versa are prevented. So we do dynamic memory
allocation inside these classes.
Whenever we have dynamic memory allocation inside a class, we have to provide few
things. We must provide a constructor that does the memory allocation for us producing a
well-formed object.
We must provide a copy constructor that is able to create fully formed copies of the
objects. That means is should not only make the copies of the values of the pointers but it
should give the pointers new values by allocating new memory for the object. And should
copy the values of the original object into this new memory location.
Page 510
We must provide an assignment operator. This operator should be able to check the selfassignment
and can assign one object to the other in a proper fashion using the concept of
deep copy and not a shallow copy. So we allocate memory space then copy element by
element in this allocated memory.
And finally we must do de-allocation which means whenever we destroy an object and it
goes out of scope, we should free the memory allocated by that object. To do the memory
de-allocation we must provide the destructor of the class in which we free (delete) the
memory by using deletes operator.


You should write small programs to examine the working of these rules. You can check
this if we allocate memory and do not delete it in the destructor. Then the next time,
when we execute the program it will allocate a new memory. We can find that which
memory is assigned by displaying the value of the pointer (not the value it points too). It
will be a number with 0x-notation i.e. it will be in hexadecimal. We don’t care about the
exact value but we will find that if we have provided a proper destructor. Then on the
same computer, in the same session, we execute the program, a specific address of
memory will be assigned to the program. With the proper destructor, we stop the program
and then again start it. Nine out of ten times, we get the same memory. That means we
will see the same address. Nine times out of ten is because the operating system can use
this memory somewhere else between the times of two executions of the program. If we
do not provide a destructor i.e. we do not deallocate the memory, it is necessary that each
time we will get a new memory. The previous memory is being wasted. You can prove it
by yourselves by writing small programs.

<Previous Lesson

Introduction to Programming

Next Lesson>


Lesson Plan


Go to Top

Copyright © 2008-2013 zainbooks All Rights Reserved
Next Lesson
Previous Lesson
Lesson Plan
Go to Top