<Previous Lesson

Introduction to Programming

Next Lesson>

Lesson#28

Lesson 28

Summary


Lecture Overview
Memory Allocation in C
Memory Allocation in C++
new Operator and Classes
Example Program 1
Classes and Structures in C++
new Operator and Constructors
delete Operator and Classes
Example Program 2
new, delete outside Constructors and Destructors
main() Function and Classes
Class Abstraction
Messages and Methods
Classes to Extend the Language
Tips


Lecture Overview


In the previous lectures, we have been discussing about Classes, Objects, Constructors
and Destructors. In this lecture we will take them further while discussing Memory
Allocation.
- We’ll see how the memory allocation is done in C++, while discussing memory
allocation in C?
Page 347
- How C++ style is different from the C-style of allocation discussed earlier?
- What are the advantages of C++ approach as compared to that of C?

Memory Allocation in C


Before further proceeding with the concept of memory, it is better to know what else we
can create with classes besides objects.
Recapturing of the concept of ‘structures’ can help us to move forward. Consider the
following statement.
struct abc
{
int integer;
float floatingpoint;
};
We could have declared a structure object as:
struct abc xyz; // Declared an object of structure type
and access data members inside structure by using dot operator (“.”) as:
xyz.integer = 2134;
xyz.floatingpoint = 234.34;
Similarly, we could have a pointer to a structure object as:
struct abc* abcPtr; // Declared a pointer of a structure type
abcPtr = xyz; // Pointer is pointing to xyz object now
We can access the individual data member as:
abcPtr->integer = 2134;
abcPtr->floatingpoint = 234.34;
We can have pointers to different data structures, similarly, pointer to a class object. Here
we are going to discuss about Pointers, Classes and Objects.
Let’s start by talking about memory allocation. We introduced few functions of memory
allocation in C: malloc(), calloc() and realloc(). Using these functions, memory is
allocated while the program is running. This means while writing your program or at
compile time, you don’t need to know the size of the memory required. You can allocate
memory at runtime (dynamically) that has many benefits. The classic example will be of
an array declared to store a string. If the length of the actual string is lesser than the size
of the array, then the part that remains unoccupied will be wasted. Suppose we declare an
array of length 6 to contain student name. It is alright if the student name is let’s say

Jamil but what will happen for the student named Abdul Razzaq. This is a case where
dynamic memory allocation is required.
Page 348
In C language, the region of memory allocated at runtime is called heap. However, in
C++, the region of available memory is called free store. We have different functions to
manipulate memory in both C and C++.
You know that while using malloc(), we have to tell the number of bytes required from
memory like:
malloc(number of bytes required to be allocated);
Sometimes, we also do a little manipulation while calculating the number of bytes
required to be allocated: i.e.
malloc( 10 * ( sizeof(int) ) );
The malloc() returns a void pointer (void *). A pointer that points to a void type of
memory. So in order to use this memory, we have to cast it to our required type. Suppose,
we want to use it for ints. For this purpose, you will cast this returned void pointer to int
*
and then assign it to an int * before making its further use. The following code is an
example of malloc() usage.
class Date
{
public:
Date( ) ;
Date(int month, int day, int year);
~Date ( ) ;
setMonth( int month ) ;
setDay( int day ) ;
setYear( int year ) ;
int getDay ( ) ;
int getMonth ( ) ;
int getYear ( ) ;
setDate(int day, int month, int year);
private:
int month, day, year;
};
Date *datePtr; // Declared a pointer of Date
type.
int i;
datePtr = (Date *) malloc( sizeof( Date ) ); // Used malloc() to allocate
memory
i = datePtr->getMonth(); // Returns undefined month value
So there is some house-keeping involved during the use of this function. We have to
determine the number of bytes required to be allocated and cast the returned void pointer
to our required type and then assign it to a variable pointer. Lastly, the memory returned
from this function is un-initialized and it may contain garbage.
Page 349
The contrasting function used to free the allocated memory using malloc() is free()


function. As a programmer, if you have allocated some memory using malloc(), it is your
responsibility to free it. This responsibility of de-allocation will be there while using C++
functions. But these new functions are far easier to use and more self-explanatory.

Memory Allocation in C++


The memory allocation in C++ is carried out with the use of an operator called new.
Notice that new is an operator while the malloc() was a function. Let’s see the syntax of

new operator through the following example.
new int;
In the above statement, the new operator is allocating memory for an int and returns a
pointer of int type pointing to this region of memory. So this operator not only allocated
required memory but also spontaneously returned a pointer of required type without
applying a cast.
In our program, we can write it as:
int *iptr;
iptr = new int;
So while using new operator, we don’t need to supply the number of bytes allocated.
There is no need to use the sizeof operator and cast the pointer to the required type.
Everything is done by the new operator for us. Similarly, new operator can be used for
other data types like char, float and double etc.
The operator to free the allocated memory using new operator is delete. So whenever, we
use new to allocate memory, it will be necessary to make use of ‘delete’ to de-allocate
the allocated memory.
delete iptr;
The delete operator frees the allocated memory that is returned back to free store for
usage ahead.
What if we want to allocate space for any array? It is very simple. Following is the
syntax:
new data_type [number_of_locations];
For example, we want to allocate an array of 10 ints dynamically. Then the statement
will be like this:
int *iptr;
iptr = new int[10];
What it does is, it tries to occupy memory space for 10 ints in memory. If the memory is
occupied successfully, it returns int * that is assigned to iptr.
Page 350
Whenever we allocate memory dynamically, it is allocated from free store. Now we will
see what happens if the memory in the free store is not sufficient enough to fulfill the
request. malloc() function returns NULL pointer if the memory is not enough. In C++, 0


is returned instead of NULL pointer. Therefore, whenever we use new to allocate
memory, it is good to check the returned value against 0 for failure of the new operator.
Remember, new is an operator,it is not a function. Whenever we use new, we don’t use
parenthesis with it, no number of bytes or sizeof operator is required and no cast is
applied to convert the pointer to the required type.

delete operator is used to free the memory when the allocation is done by using new as
shown below:
int *iptr;
iptr = new int [10]; // Memory for 10 ints is allocated dynamically.
delete iptr; // Allocated is freed and returned to the free store.
Can we apply the concept of dynamic memory allocation/deallocation while using
new/delete with classes and objects? The answer is obviously yes.

new Operator and Classes


As we declare a pointer to a primitive datatype, similarly, we can have a pointer to a
class object.
Date *dptr; // dptr is a pointer to an object of type Date.
Now, we create the object using the
new operator. Remember, the basic definition of a class
i.e. it is a user-defined data type. In other words, the language has been extended to a
programmer to have user defined data types. When we use them in our programs, these
are used in the same manner as the primitive data types.
dptr = new Date;

Process
(Program in memory)


Date class
main ( )
{
Date* = new Date();
. . .
. . .
}
BasicData class
dptr

Free Store


0
0
0

Page 351
Whatever amount of memory is required for a Date object, is allocated from the free
store. A pointer to of Date type is returned back and assigned to the dptr pointer variable.
Is this all what new is doing? If it is so, can we use malloc() function by providing
number of bytes required for Date object with the help of sizeof operator. The answer to
this question lies in the further discussion.
Date mydate;
cout << sizeof (mydate);
As discussed in the last lecture, whenever we instantiate an object of a class, the data
members are allocated for each object. However, the member functions occupy a
common region in memory for all objects of a class. Therefore, sizeof operator returns
the size of the data-members storage excluding the member functions part. In the above
statement, the sizeof operator returns the sum of the sizes of three integers day, month


and year, declared in the Date class.
The amount of memory allocated in the above statement using new (dptr = new
Date;) is same as reflected in the following statement:
dptr = (Date *) malloc( sizeof(Date) );
The new operator in the above statement ( dptr = new Date;) has automatically
determined the size of the Date object and allocated memory before returning a pointer of

Date * type. Is this all what new is doing? Actually, it is doing more than this. It is also
creating an object of type Date. C functions like malloc() do nothing for object creation.
Rather these C functions allocate the required number of bytes and return a void *


pointing to the allocated memory where the memory might contain garbage. But the new


operator not only allocates the memory after automatically determining the size of the
object but also creates an object before returning a pointer of object’s class type.
Additionally, within the call to the new operator, the memory assigned to the created
object with the use of new operator can be initialized with meaningful values instead of
garbage (think of C functions like malloc() ).
How the data members are initialized with meaningful values? Actually, a constructor is
called whenever an object is created. Inside the constructor, individual data members can
be initialized. The C++ compiler generates a default constructor for a class if the
programmer does not provide it. But the default constructor does not perform any data
members initialization. Therefore, it is good practice that whenever you write a class, use
a constructor function to initialize the data members to some meaningful values.
Whenever new operator is used to create an object, following actions are performed by it:
- It automatically determines the size of the memory required to store that object,
leaving no need for the use of sizeof operator.
- Calls the constructor of the Class, where the programmers normally write
initialization code.
Page 352
- Returns pointer of the class type that means no casting is required.
Hence, new operator is extremely useful, powerful and a good way of allocating memory.
Let’s suppose, we want to allocate space for 10 ints as under:
int * iptr;
iptr = new int [10];
This new statement allocates contiguous space for an array of 10 ints and returns back
pointer to the first int. Can we do this operation for objects of a class? The answer to this
question is yes. The syntax in this case will be identical. To create an array of 10 objects
of Date type, following code is written:
Date * dptr;
dptr = new Date [10];
int day = dptr->getDay();
Here the new operator allocates memory for 10 Date objects. It calls the default or
parameter-less constructors of the Date class and returns the pointer to the first object,
assigned to the dptr variable. Arrow operators (->) is used while accessing functions or
data members from the pointer variable.

Example Program 1


/* Following program demonstrates the new operator. This program has the problem of
memory leak because delete operator is not called for the allocated memory. */
#include <iostream.h>
class MyDate
{
public: // public members are below
/* Parameterless constructor of MyDate class */
MyDate( )
{
cout << "\n Parameterless constructor called ...";
month = day = year = 0; // all data member initialized to 0
}
/* Parameterized constructor of MyDate class. It assigns the parameter values to the
……..data members of the class */
MyDate(int month, int day, int year)
{
cout << "\n Constructor with three int parameters called ...";
Page 353
this->month = month; // Notice the use of arrow operator ( -> )
this->day = day;
this->year = year;
}
/* Destructor of the MyDate class */
~MyDate ( )
{
cout << "\n Destructor called ...";
}
/* Setter function for the month data member. It assigns the parameter value to
the month data member */
void setMonth ( int month )
{
this->month = month;
}
/* Setter function for the day data member. It assigns the parameter value to the

day data member */
void setDay ( int day )
{
this->day = day;
}
/* Setter function for the year data member. It assigns the parameter value to the

year data member */
void setYear ( int year )
{
this->year = year;
}
/* Getter function for the day data member. It returns the value of the day data
member */
int getDay ( )
{
return this->day;
}
/* Getter function for the month data member. It returns the value of the

month data member */
int getMonth ( )
{
Page 354
return this->month;
}
/* Getter function for the year data member. It returns the value of the year data
member */
int getYear ( )
{
return this->year;
}
/* A function to set all the attributes (data members) of the Date object */
void setDate ( int day, int month, int year )
{
this->day = day;
this->month = month;
this->year = year;
}
private: // private members are below
int month, day, year;
};
main(void)
{
MyDate *dptr; // Declared a pointer dptr to MyPointer class object
dptr = new MyDate [10]; // Created 10 objects of MyDate and assigned the
// pointer to the first object to dptr pointer variable.
// delete should have been called here before the program terminates.
}
The output of this example program is as follows:
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Notice that the constructor is called 10 times with 10 new calls but there is no call to
destructor. What is the reason? The objects are created with the new operator on free
Page 355
store, they will not be destroyed and memory will not be de-allocated unless we call

delete operator to destroy the objects and de-allocate memory. So memory allocated on
free store is not de-allocated in this program and that results in memory leak. There is
another point to be noted in this example program, which is not relevant to our topics of
discussion today that all the functions are requested to be inline automatically as the
functions are defined within the class body.

Classes and Structures in C++


Structures and classes in C++ are quite similar. C++ structure is declared with the same
keyword struct as in C. Unlike C structure, C++ structure can have data and member
functions. The difference between class and structure is of visibility. Every data member
or function written inside the structure is public (visible from outside) by default unless
declared otherwise. Similarly, everything declared inside a class is private (not visible
from outside) by default unless declared as public.
While writing classes, good programming practice is to write private keyword explicitly,
despite the fact that this is the default behavior. Similarly, while writing structures, it is
good to write the public keyword explicitly. This averts confusion and increases
readability.
Another good practice is to write public or private keywords only once in the class or
structure declaration, though there is no syntactical or logical problem in writing them
multiple times.
Also remember while writing a class or a structure that once a keyword is written, say

public, the declarations falling below this keyword will be public until the private


keyword is mentioned.
There is another keyword protected. We are not using this keyword in this course because
that deals with inheritance that is a part of Object Oriented Programming, a separate
course.

new Operator and Constructors


It is clear that whenever new operator is called to create an object, the constructor is also
called for that object. What will happen if we have to call new from inside a constructor
function. Can we do that? The answer is definitely yes. There are times when we have to
do dynamic memory allocation or create new objects from inside a constructor. For
example, we have a Student class with attributes i.e. roll number, age, height and
Student class
{
public:
Student(char* name)
{
= new char (strlen(name)+1) ;
srcpy( this->name, name) ;
}
. . .
}
main ( )
{
. . .
}
BasicData class

Process
(Program in memory)
Free Store


J
m
a
i
l
\0
this->name

Page 356

name. The attributes like roll number, age and height can be contained in ints or floats
but the name attribute will require a string. Because of the nature of this attribute (as it
can have different lengths for different students), it is better to use dynamic memory
allocation for this. So we will use new operator from within the constructor of Student


class to allocate memory for the name of the student.
We know whenever we use new to allocate memory, it is our responsibility to de-allocate
the memory using the delete operator. Failing which, a memory leak will happen.
Remember, the memory allocated from free store or heap is a system resource and is not
returned back to the system ( even if the allocating program terminates ) unless explicitly
freed using delete or free operators.
Now, we will see how the delete works for objects and what is the syntax.

delete Operator and Classes


As in our Student class, as we will be allocating memory from within the constructor of
it. Therefore, there is a need to call delete to de-allocate memory. What is the appropriate
location inside the class Student to call delete operator to de-allocate memory? In
normal circumstances, the location is the destructor of a class (Student class’s destructor
in this case). The destructor is used to de-allocate memory because it is called when the
object is no more needed or going to be destroyed from the program’s memory. So this is
the real usefulness of destructors that these are used to release the system resources
including memory occupied by the objects.
As a thumb rule , whenever there is a pointer data member inside our class and pointer is
being used by allocating memory at runtime. It is required to provide a destructor for that
class to release the allocated memory. A constructor can be overloaded but not a
destructor. So there is only one destructor for a class. That one destructor of a class must
do house keeping before the object is destroyed. Normal data members int, char, float


and double, not allocated using malloc() or new operator, don’t need to be de-allocated
using free() or delete. These are automatically destroyed.
Let’s be sure that free() is used with malloc() function while delete operator with new


operator. Normally, new will be called in a constructor. However, delete will be called in
the destructor.

Example Program 2


/* Following program demonstrates the new and delete operators. It deallocates the
memory properly before terminating. */
#include <iostream.h>
class MyDate
Page 357
{
public: //public members are below
/* Parameterless constructor of MyDate class */
MyDate( )
{
cout << "\n Parameterless constructor called ...";
month = day = year = 0; // all data member initialized to 0
}
/* Parameterized constructor of MyDate class. It assigns the parameter values to the
……..data members of the class */
MyDate(int month, int day, int year)
{
cout << "\n Constructor with three int parameters called ...";
this->month = month; // Notice the use of arrow operator ( -> )
this->day = day;
this->year = year;
}
/* Destructor of the MyDate class */
~MyDate ( )
{
cout << "\n Destructor called ...";
}
/* Setter function for the month data member. It assigns the parameter value to
the month data member */
void setMonth ( int month )
{
this->month = month;
}
/* Setter function for the day data member. It assigns the parameter value to the

day data member */
void setDay ( int day )
{
this->day = day;
}
/* Setter function for the year data member. It assigns the parameter value to the

year data member */
void setYear ( int year )
Page 358
{
this->year = year;
}
/* Getter function for the day data member. It returns the value of the day data
member */
int getDay ( )
{
return this->day;
}
/* Getter function for the month data member. It returns the value of the

month data member */
int getMonth ( )
{
return this->month;
}
/* Getter function for the year data member. It returns the value of the year data
member */
int getYear ( )
{
return this->year;
}
/* A function to set all the attributes (data members) of the Date object */
void setDate ( int day, int month, int year )
{
this->day = day;
this->month = month;
this->year = year;
}
private: // private members are below
int month, day, year;
};
main(void)
{
MyDate *dptr; // Declared a pointer dptr to MyPointer class object
dptr = new MyDate [10]; // Created 10 objects of MyDate and assigned the
// pointer to the first object to dptr pointer variable.
delete [] dptr; // Deleted (freed) the assigned memory to the objects
}
Page 359
The output of this example program is as follows:
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Parameterless constructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
Destructor called ...
It is very clear from the output that the destructor for all the objects is called to avert any
memory leak. The memory allocated using new operator is being de-allocated using the
delete operator. Notice the syntax of delete while de-allocating an array, the brackets ([])
precedes the name of the array after the delete operator.

new, delete outside Constructors and Destructors


Can new be called from some location other than constructor? The answer is yes and we
usually need to do that. Suppose, we have an object of Student class. The name of the
student is: Abdul Khaliq. So for the name attribute, the space is allocated dynamically to
store the string Abdul Khaliq. When our program is running and we have already
allocated space for the Abdul Khaliq string using the new operator, after sometime, we
are required to increase the size of the string. Let’s say we want to change the string to

Abdul Khaliq Khan now.
So what we can do, without destroying this student object:
De-allocate the name previously occupied string using the delete operator, determine the
size of memory required with the help of strlen() function, allocate the memory required
for the new string Abdul Khaliq Khan using the new operator and finally assign the
returned pointer to the name data member.
Hence, we can call new and delete operators, not only outside the class to create objects
but also within the class. The objects of the same class can have different sizes of
Page 360
memory space like in case of objects of Student class, student 1 object can be of one size
and student 2 object can be of an another size, primarily varying because of string name.
But independent of this object size, the destructor of the object remains the same and deallocates
memory for different objects regardless of their different sizes. delete operator
is used from within the destructor to deallocate the memory. We call delete operator to
determine the size of the memory required to be de-allocated and only provide it a pointer
pointing to it.
Please note that C functions like malloc() and free() functions can also be used from
within C++ code. But while writing classes inside C++ code, we prefer to use new and

delete operators as they are designed to work with classes and objects.

main() Function and Classes


We used to discuss about main() function a lot while writing our programs in C. You
might have noticed that while discussing about classes and objects, we are not talking
about the main() function. This does not mean that main() function is not there in C++. It
is there but it does not contain as much code in C++ . But as you go along and write your
own classess, you will realize that almost 90% of your program’s code lies inside the
class definitions. So firstly we write our classes and main() function is written after
classes have been defined. That is why the main() function is very small. Our example
programs clearly depict this fact.

Class Abstraction


Whenever we write a class, we think about its users. Who are the ones going to use this
class? The users are not only the main() function of the program but also our colleagues
around us. Remember, we only expose interface to our users and not the class
implementation. All what users need to know is provided in the interface, the methods
signatures and what can be achieved by calling that method. The users do not need to
know how the functions or interfaces are implemented, what are the variables, how is the
data inside and how is it being manipulated, it is abstract to the users.

Messages and Methods


When we create an object, we ask that object to do something by calling a function. This
way of asking objects in Windows operating system is called Messaging or in other
words function calling is sending a message to the object. Sending a message is a
synonym of calling a method of an object. The word ‘method’ is from the fact that it is a
way of doing something. So the whole program is sending messages and getting
responses back. It is a different way of looking at things.
Page 361
Notice lot of things have been repeated in this lecture many times, the reason is that now,
you are required to think differently, more in terms of classes and objects. There are lots
of exciting things coming up to be covered later.

Classes to Extend the Language


We know that in C, there is no data type for complex numbers. Therefore, we needed to
define our own class for complex numbers. We might use double data type for real and

imaginary parts. From basic Mathematics, we also know that whenever two complex
numbers are added, real part of one complex number is added into the real part of other
complex number and imaginary part of one complex number is added into the imaginary
part of other complex number. We might write a function for this operation and might
call this as cadd(). We might also write other functions for multiplication and division. In
C++, the operators like ‘+’, ‘*’ and ‘/’ can be overloaded, therefore, we could overload


these operators for complex numbers, so that we could easily use these ordinary addition,
multiplication, and division operators for complex numbers. Actually, we don’t need to
write this class on our own because this is already been provided in many C++ libraries.
Remember, there is no primitive data type in C++ for complex numbers but a class has
been written as part of the many C++ libraries. Moral of the above paragraph is; by using
user defined data types i.e., classes, we can now really extend the language.

Tips


- Classes are one way of extending the C++ language.
- Whenever new operator is used, no number of bytes or sizeof operator is required and
no cast is applied to convert the pointer to the required type.
- Whenever new operator is called to create an object, the constructor is also called for
that object. It is a good practice that whenever you write a class, use a constructor
function to initialize the data members to some meaningful values.
- The usual practice is to use constructor to allocate memory or system resources and
destructors to de-allocate or return the resources back to the system.
- In C language, the region of memory allocated at runtime is called heap. However, in
C++, the region of available memory is called free store. There are different
functions in C and C++ to manipulate memory at runtime. However, all C functions
are useable in C++ code.
- The memory allocated from free store or heap is a system resource and is not
returned back to the system unless explicitly freed using delete or free operators.
Page 362
- If the memory in the free store is not sufficient enough to fulfill the request, malloc()


function returns NULL pointer. Similarly, the new function returns 0 in case the
request could not be fulfilled.
- Whenever we use new operator, the returned value from the new should be checked
against 0 for any possible failures.
- While writing classes, good programming practice is to write private keyword
explicitly, despite the fact that this is the default scope. Additionally, the good
practice is to write public or private keywords only once in the class or structure
definitions, though there is no syntactical or logical problems in writing them
multiple times.

<Previous Lesson

Introduction to Programming

Next Lesson>

Home

Lesson Plan

Topics

Go to Top

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