Handout 6 CSM 1101
Handout 6 CSM 1101
Handout 6 CSM 1101
What is Pointer? :
Pointer variable is a special variable, which stores the address of other variable. If a
pointer variable stores the address of a char variable, we call it a character pointer and so
on.
Normally a variable directly contains a specific value. A pointer, on the other hand,
contains an address of a variable that contains a specific value. Pointers like any other
variables must be declared before they can be used.
Examples:
int *j -------- Means the value at address contained in j is an int OR in other words j is
an integer pointer.
Int **k ------ Means the value at address contained in *k is an int.
Pointers – Why?
Achieve call by reference (i.e. write functions which change their parameters).
We can return more than values from the function by using Pointers (output
parameters)
1
Handle arrays efficiently.
Handle structures (records efficiently).
Create liked lists, trees, graphs etc.
Care must be taken when using pointers since there are no safety features.
A pointer variable enables you to change the value of another variable without
using that variable’s name.
To learn about new and delete operators in C++ for dynamic memory
1)
#include<iostream.h>
void main( )
{
int *a, b=10;
a=&b;
cout <<a<<endl<<endl;
cout<<*a<<endl<<endl;
cout<<b<<endl<<endl;
}
Output:
2)
#include <iostream.h>
int main()
{
int a; // a is an integer
int *b; // b is a pointer to an integer
2
a = 7;
b = &a; // b assigned address of a
} // end main
#include <iostream.h>
main()
{ int count = 10, x, *ip;
ip = &count;
x = *ip;
cout<<"count = "<<count<<" x = "<<x<<endl;
}
b).
#include <iostream.h>
void main()
{ int i1, i2, *p1, *p2;
i1 = 5;
p1 = &i1;
i2 = *p1 / 2 + 10;
p2 = p1;
cout<<"i1= "<<i1<<" i2= "<<i2<<" *p1= "<<*p1<<" *p2 = "<<*p2<<endl;
}
Pointer Arithmetic:
On incrementing a pointer, it points to the immediately next location of its type. The way
a pointer can be incremented, it can be decremented as well, to point to earlier locations.
3
Suppose following declaration statements are given:
After execution of these arithmetic statements the new content of x, y, z will be:
4004, 5004, 6001.
Till now we used only the functions that returned zero or one value through the return
statement. To return more than one value, we need to use the output parameters, which
are pointers. Note that when we use output parameters in functions we declare those
functions as void returning functions because they are not returning single value by return
statement.
Consider the example of a function that accepts the radius of a circle from the main
program and returns the area and circumference of a circle by using the output
parameters.
Example:
#include <iostream.h>
void area_circum (double radius, double *area, double * circum) ; // function
prototype
void main ()
{
double r, a, c ;
cout<<"Enter the radius of the circle\n" ;
cin>>r ;
area_circum (r, &a, &c) ; //function call that passes the address of the variables a and c
cout<<"The area is = "<<a <<a<<" and circumference is = "<<c<<endl ; // output results
}
4
void area_circum (double radius, double *area, double * circum)
{
*area = 3.14 * radius * radius ; //indirect reference to variable a of main program
*circum = 2 * 3.14 * radius ; //indirect reference to variable c of main program
}
Here the variables area of function area_circum and a of main both refer to the same
memory location. Similarly, the variables circum of function area circum and c of main
both refer to the same memory location.
Note that when the function is called in the main program, the output parameters have &
attached to them before their name. When the output parameters are used in the function,
they are used with * attached to them before their name.
Just like we can have pointers to simple data types we can have pointers to arrays.
However, when we define a pointer that will be used to point to the elements of an array
we don’t designate the pointer as “pointer to array”, rather we designate the pointer as
pointing to the type of element that is contained in the array. If we have an array of
integers called values, then we can define a pointer called values_pointer, which can be
used to access the integers contained in this array with the statement
int *values_pointer ;
In order to set values_pointer to point to the first element in the values array, we simply
write
values_pointer = values ; OR
values_pointer = &values[0] ;
Note that the pointer values_pointer is pointing to the first element in the array. So,
*values_pointer
can be used to access the first integer of the values array, i.e., values[0]. To reference
values[3] through the values_pointer variable, we can add 3 to its value and then apply the
indirection operator:
*(values_pointer + 3)
5
*(values_pointer + 10) = 27 ;
To point values_pointer to the second element of the values array values we can write
values_pointer = &values[1] ;
OR equivalently as values_pointer += 1 ; OR ++values_pointer ;
Similarly, to point values_pointer to the nth element of the array values we write
values_pointer += n ;
Example:
Consider the program to sum the elements of an integer array values of size 10 using
the pointer.
#include<iostream.h>
void main ()
{
int values [10] = { 3, 7, -9, 3, 6, -1, 7, 9, 1, -5 } ;
int sum = 0, *values_pointer, *array_end ;
In the above for loop, the statement values_pointer = values causes the pointer
values_pointer to point to the first element in the array. The statement values_pointer <
array_end checks whether the end of the array values has been reached, the statement
++values_pointer increments the pointer each time to point to the next element in the
array values.
new and delete operators in C++ for dynamic memory:
6
One use of dynamically allocated memory is to allocate memory of variable size
which is not possible with compiler allocated memory except variable length arrays.
The most important use is flexibility provided to programmers. We are free to
allocate and deallocate memory whenever we need and whenever we don’t need
any more. There are many cases where this flexibility helps. Examples of such
cases are Linked List, Tree, etc.
For normal variables like “int a”, “char str[10]”, etc, memory is automatically allocated
and deallocated. For dynamically allocated memory like “int *p = new int[10]”, it is
programmers responsibility to deallocate memory when no longer needed. If programmer
doesn’t deallocate memory, it causes memory leak (memory is not deallocated until
program terminates).
C uses malloc() and calloc() function to allocate memory dynamically at run time and
uses free() function to free dynamically allocated memory. C++ supports these functions
and also has two operators new and delete that perform the task of allocating and freeing
the memory in a better and easier way.
This discussion is all about new and delete operators.
new operator:
The new operator denotes a request for memory allocation on the Heap. If sufficient
memory is available, new operator initializes the memory and returns the address of the
newly allocated and initialized memory to the pointer variable.
Syntax to use new operator: To allocate memory of any data type, the syntax is:
Example:
7
int *p = NULL;
p = new int;
OR
Initialize memory: We can also initialize the memory using new operator:
Allocate block of memory: new operator is also used to allocate a block(an array) of
memory of type data-type.
Example:
int *p = new int[10]
Dynamically allocates memory for 10 integers continuously of type int and returns
pointer to the first element of the sequence, which is assigned to p(a pointer). p[0] refers
to first element, p[1] refers to second element and so on.
There is a difference between declaring a normal array and allocating a block of memory
8
using new. The most important difference is, normal arrays are deallocated by compiler
(If array is local, then deallocated when function returns or completes). However,
dynamically allocated arrays always remain there until either they are deallocated by
programmer or program terminates.
If enough memory is not available in the heap to allocate, the new request indicates
failure by throwing an exception of type std::bad_alloc and new operator returns a
pointer. Therefore, it may be good idea to check for the pointer variable produced by new
before using it program.
delete operator:
Since it is programmer’s responsibility to deallocate dynamically allocated memory,
programmers are provided delete operator by C++ language.
Syntax:
// Release memory pointed by pointer-variable
delete pointer-variable;
Here, pointer-variable is the pointer that points to the data object created by new.
Examples:
delete p;
delete q;
9
// Release block of memory
// pointed by pointer-variable
delete[] pointer-variable;
Example:
// It will free the entire array
// pointed by p.
delete[] p;
Example:
int main ()
{
// Pointer initialization to null
int* p = NULL;
10
int n = 5;
int *q = new int[n];
if (!p)
cout << "allocation of memory failed\n";
else
{
for (int i = 0; i < n; i++)
q[i] = i+1;
return 0;
}
Sample output:
Exercises
a).
#include<iostream.h>
int main(void)
11
{
char g=’z’;
char c=’a’;
char *p;
p=&c;
cout << *p <<endl;
p=&g;
cout << *p<<endl;
return 0;
}
b).
#include<iostream.h>
void main( )
{
int m=7,y, *p1, *p2;
p1=&m;
p2=&y;
*p2=9;
cout<<"m= "<<m<<endl;
cout<<"y= "<<y<<endl;
p2=p1;
cout<<"*p1= "<<*p1<<endl;
cout<<"*p2= "<<*p2<<endl;
}
c).
#include<iostream.h>
*X = *X + 2;
Y = *X * 4;
return Y;
}
void main()
{
int a=1,b=2;
12
b=f(&a);
cout<<a<<" "<<b<<endl;
a=f(&b);
cout<<a<<" "<<b<<endl;
d).
#include<iostream.h>
void test1(int m, int n)
{
m=5;
n=24;
}
int main()
{
int a=10, b=16;
cout <<"a=”<<a<<”b=”<<b<<endl;
13
cout <<"a=”<<a<<”b=”<<b<<endl;
return 0;
}
e).
int myfunction(int p, int q)
{
if (p == q)
return p;
else if (p < q)
return myfunction(q - p, p);
else
return myfunction(p - q, q);
}
void main()
{
int result;
result=myfunction(20,5);
cout<<result<<endl;
}
====================
14