EC-200 Data Structures
LAB MANUAL - 01
Course Instructor: Lecturer Anum Abdul Salam
Lab Engineer: Lab Engineer Kashaf Raheem
Student Name: _______________________________________________
Degree/ Syndicate: ____________________________________________
Trait Obtained Maximum
Marks Marks
R1 Application Functionality 20
20%
R2 Specification & Data 30
structure implementation
30%
R3 Reusability 10
10%
R4 Input Validation 10
10%
R5 Efficiency 20
20%
R6 Delivery 10
10%
R7 Plagiarism above 60% 0
Total 10
Total Marks = O𝒃𝒕𝒂𝒊𝒏𝒆𝒅 𝑴𝒂𝒓𝒌𝒔 (∑6𝟏 𝑹𝒊 ∗ 𝑹7)
Lab # 01: Introduction to pointers and Dynamic Memory
Lab Objective:
To practice pointers and dynamic memory applications.
Lab Description:
A pointer is a variable whose value is the address of another variable. Like any variable or
constant, you must declare a pointer before you can work with it.type *var-name; There are few
important operations performed when using pointers are
1. Define a pointer variable.
2. Assign the address of a variable to a pointer.
3. Access the value at the address available in the pointer variable.
Defining a Pointer Variable Pointer Variables To access num using iptr and
Assignment: indirection operator *
int *iptr; int num=25; cout << iptr; // prints 0x4a00
// iptr can hold the address of an int
iptr = # cout << *iptr; // prints 25
Figure 1.1 Dereferencing pointers to access memory location
Value of memory location towards which pointer is pointing can be changed using pointers
*ptr_nam=val;For example *iptr=8;
Figure 1.2: Changing the content of location using pointers
It is always a good practice to assign the pointer NULL to a pointer variable in case you do not
have exact address to be assigned.
Example
void main () {
int *ptr=NULL;
if (ptr) {// succeeds if p is not null}
if (!ptr) {// succeeds if p is null}
If all unused pointers are given the null value you can avoid the accidental misuse of an
uninitialized pointer. Many times, uninitialized variables hold some junk values and it becomes
difficult to debug the program.
Pointer Rules Summary
1. A pointer stores a reference to its pointee. The pointee, in turn, stores something useful.
2. The dereference operation on a pointer accesses its pointee. A pointer may only be
dereferenced after it has been assigned to refer to a pointee. Most pointer bugs involve
violating this one rule.
3. Allocating a pointer does not automatically assign it to refer to a pointee. Assigning the
pointer to refer to a specific pointee is a separate operation which is easy to forget.
4. Assignment between two pointers makes them refer to the same pointee which introduces
sharing.
Static Memory Allocation:
In the static memory allocation, the amount of memory to be allocated is predicted and pre
known Memory is allocated during the compilation itself. All the declared variables declared
normally, are allocated memory statically.
Example
void main nt sqr(int val)
{int a=9; {return val*val;
cout<<sqr(a); }
}
Dynamic Memory Allocation:
Variables declared and used locally inside a function definition are destroyed, when declared
variables within a function scope are needed to be used by other functions without creating an
overhead by copying these variables via function's return value.
1. Allocate memory when required.
2. Use it by initializing to some value.
3. Deallocate the memory when no more required.
Memory Allocation Memory Initialization Memory deallocation
ptrtype* ptrname; *ptrname=value; delete ptrname;
pvalue = new ptrtype; void main void main
void main { {
{ int*p; int*p;
int*p; p=new int; p=new int;
p=new int; *p=9; *p=9; delete p;
} } }
Constructors
A constructor in C++ is a special function having the same name as that of its class which is
used to initialize some valid values to the data members of an object. It is executed automatically
whenever an object of a class is created. The only restriction that applies to the constructor is that
it must not have a return type or void. It is because the constructor is automatically called by the
compiler, and it is normally used to initialize values. The compiler distinguishes the constructor
from other functions of a class by its name which is the same as that of its class
Properties of constructors
1. Constructor has same name as the class itself.
2. Constructors do not have return type.
3. A constructor is automatically called when an object is created.
4. It must be placed in public section of class.
5. If we do not specify a constructor, C++ compiler generates a default constructor for
object (expects no parameters and has an empty body).
Example
class Number{
public:
int firstNumber;
int secondNumber;
Number( ){
int firstNumber = 15;
int secondNumber = 20;
void displayMethod( ){
cout<<“Numbers.”<< firstNumber <<
secondNumber <<endl;
}
};
int main( ){
// driver code
Types of Constructors
There are three types of constructors.
1. Default
2. Parametrized
3. Copy
1. Copy Constructor
A copy constructor is a function that initializes an object using another object of the same class.
In simple terms, a constructor which creates an object by initializing it with an object of the same
class, which has been created previously is known as a copy constructor. Copy constructor takes
a reference to an object of the same class as an argument.
Copy Constructor
class Integer {
public:
int x, y;
// Parametrized Constructor declared
Integer( int a, int b) {
x = a;
y = b;
// Copy Constructor declared
Integer (Integer &p) {
x=p.x;
y=p.y;
void displayMethod( ){
cout<<“Numbers.”<< x << “ ”<<y<<endl;
};
int main( ){
Integer i1(15,20);
Integer i2( i1 ); // first method
Integer i3 = i2; // second method
i1.displayMethod( );
i2.displayMethod( );
i3.displayMethod( );
return 0;
Destructor
It is automatically called when object goes out of scope. Destructor release
memory space occupied by the objects created by constructor. In destructor,
objects are destroyed in the reverse of an object creation. Destructor has the
same name as their class name preceded by a tilde (~) symbol. The
destructor does not have arguments.
A destructor function is automatically called when the object goes out of
scope:
1. The functions ends.
2. The program ends.
3. A block containing local variables end.
4. A delete operator is called.
Dangling Pointers:
The delete operator does not delete the pointer it takes the memory being pointed to and returns
it to the heap. It does not even change the contents of the pointer. Since the memory being
pointed to is no longer available (and may even be given to another application), such a pointer is
said to be dangling.
Memory Leaks and Bad pointers
Memory leaks when it is allocated using the new operator but not returned to the heap using
the delete operator. When a pointer is dereferenced but not allocated any memory, such pointer is
called bad pointer.
Shallow Copy vs Deep Copy
Shallow Copy Deep Copy
When we create a copy of object by copying When we create an object by copying data of
data of all member variables as it is, then it is another object along with the values of
called shallow copy memory resources that reside outside the
object, then it is called a deep copy
A shallow copy of an object copies all of the Deep copy is performed by implementing our
member field values. own copy constructor.
A shallow copy, the two objects are not It copies all fields, and makes copies of
independent dynamically allocated memory pointed to by
the fields
LAB TASKS:
1. For each of the following, write a single statement that
performs the specified task. Assume that floating-point
variables number1 and number2 have been declared and that
number1 has been initialized to 5.6.
a) Declare the variable fPtr to be a pointer to a variable of type double
and initialize the
pointer to nullptr.
b) Can you de-refer the above pointer and display its value?
b) Assign the address of variable number1 to pointer variable fPtr.
c) Display the value of the variable pointed to by fPtr.
d) Assign the value of the variable pointed to by fPtr to variable
number2.
e) Display the value of number2.
f) Display the address of number1.
g) Display the address stored in fPtr. Is the address displayed the same
as that of number1?
2. Create a class IntStaticPointer containing a pointer to integer
(ptr) as attribute. Each instance of class should be capable of
pointing towards integer variable.
Provide `
default constructor Initializes pointer to some initial value
(NULL)
voidAllocMem(int a) allocate memory to the pointer using
static memory
void setValue(intval) Assigns the pointer to val
int getValue() returns the contents of memory to which pointer
is pointing
Destructor that displays the address and value of the location
pointed by ptr
Test Plan Output?
int main()
{
IntStaticPointer b;
int z=8;
b.AllocMem(z);
cout<<b.getValue();
mystery(b);
cout<<b.getValue();
}
void mystery(IntStaticPointer &b)
{
int a=100;
b.AllocMem(a);
cout<<b.getValue();
}
Identify how the given code has logical errors. Can you correct them?
3. Design a class to represent a to-do list, where each task is dynamically added or
removed. A task should include task id and deadline.
Provide the following:
A default constructor to initialize an empty to-do list.
A parameterized constructor to initialize a to-do list with an initial
task.
A copy constructor to create a deep copy of a to-do list.
A destructor to release allocated memory.
Functions to be performed
AddTask: Add a new task to the list.
RemoveTask: Remove a task by name or index.
DisplayTasks: Display all tasks in the list.
THINK!!!
1. Is constructor overriding possible in OOP? If no, why?
2. Why do we need a user-defined destructor, when do we need them?
3. Why pointers should be copied deeply instead of shallow copy?