You are on page 1of 44

Jimma University

School of Computing and


Informatics.

Fundamental of Programming II

Chapter two: Pointer in C++

Jimma, Ethiopia.
Objective of the chapter

Learn about the pointer data type and pointer variables

Explore how to declare and manipulate pointer variables

Learn about the address of operator and the dereferencing operator

Learn about pointer operation

Discover dynamic variables

Explore how to use the new and delete operators to manipulate dynamic
variables.

Learn about dynamic array

2
Pointer Data Type and Pointer Variables

Data type as a set of values together with a set of operations.


 Recall that the set of values is called the domain of the data type. For
example, there is a data type called int.
The set of values belonging to this data type includes integers that
range between –2147483648 and 2147483647, and
 The operations allowed on these values are the arithmetic operators.
To manipulate numeric integer data in the range –2,147,483,648 to
2,147,483,647, you can declare variables using the word int. The name of
the data type allows you to declare a variable.
The values belonging to pointer data types are the memory addresses of
your computer.
As in many other languages, there is no name associated with the pointer
data type in C++. Because the domain—that is, the set of values of a
pointer data type—is the addresses (memory locations).
3
Cont..

Pointer variable is a variable whose content is an address, that is, a


memory location. It is a construct that gives you more control of the
computer’s memory. It is the memory address of a variable.

Recall that the computer’s memory is divided into numbered memory


locations (called bytes), and that variables are implemented as a sequence
of adjacent memory locations.

 An address that is used to name a variable in this way (by giving the
address in memory where the variable starts) is called a pointer because
the address can be thought of as “pointing” to the variable.

The address “points” to the variable because it identifies the variable by


telling where the variable is, rather than telling what the variable’s name
is?

4
Declaring Pointer Variables

In C++, you declare a pointer variable by using the asterisk symbol (*) between the data
type and the variable name.
The general syntax to declare a pointer variable is:

dataType *identifier;
 Where type is the data type pointed to by the pointer.
As an example, consider the following statements:

int *p;
char *ch;
 In these statements, both p and ch are pointer variables of type int and char
respectively.
 The content of p points to a memory location of type int,
 the content of ch points to a memory location of type char.
Memory addresses, or pointers, allow us to manipulate data much more flexibly;
manipulating the memory addresses of data 5can be more efficient than manipulating the
Cont…

Before discussing how pointers work, let us make the following


observations. The statement:

 int *p;, int* p;, int * p; equivalent statement:

 int* p, q; In this statement, only p is the pointer variable, not q.

 int *p, *q; declares both p and q to be pointer variables of type int.

C++ provides two operators—the address of operator (&) and the


dereferencing operator (*)—to work with pointers.

6
Address of Operator (&)

The address of a variable can be obtained by preceding the name of a


variable with an ampersand sign (&), known as reference operator, and
which can be literally translated as "address of".
In C++, the ampersand, &, called the address of operator, is a unary
operator that returns the address of its operand. For example, given the
statements:
int x;
int *p;
The statement: p = &x;
 assigns the address of x to p. That is, x and the value of p refer to the
same memory location.
Note: The actual address of a variable in memory cannot be known
before runtime.

7
Example

Consider the following code fragment:


int myvar = 25;
int *foo = &myvar;
int bar = myvar;
The values contained in each variable after the execution of this are
shown in the following diagram:

The variable that stores the address of another variable is what in C++ is
called a pointer.
8
Dereferencing Operator (*)

An interesting property of pointers is that they can be used to access the
variable they point to directly.
 This is done by preceding the pointer name with the dereference
operator (*). The operator itself can be read as "value pointed to by".
baz = *foo; This could be read as: "baz equal to value pointed to by foo",

The reference and dereference operators are thus complementary:


& is the reference operator, and can be read as "address of"
* is the dereference operator, and can be read as "value pointed to by"
9
Cont..

Let us consider the following statements:


int *p;
int num;
 In these statements, p is a pointer variable of type int, and num is a
variable of type int. Let us assume that memory location 1200 is allocated
for p, and memory location 1800 is allocated for num.

 Consider the following statements:


num = 78;
p = #
*p = 24;

10
Cont…

Consider the following statements:


int *p;
int x;
The values of &p, p, *p, &x, and x are as follows:

Suppose that the following statements are executed in the order given:
x = 50;
p = &x;
*p = 38;

11
Cont…

After the statement x = 50; executes, the values of &p, p, *p, &x, and x
are as follows:

After the statement p = &x; executes, the values of &p, p, *p, &x, and x
are as follows:

After the statement *p = 38; executes, the values of &p, p, *p, &x, and x
are as follows. (Because *p and x refer to the same memory space, the
value of x is also changed to 38.)

12
Pointer initialization

C++ does not automatically initialize variables, pointer variables must be


initialized if you do not want them to point to anything.
Pointer variables are initialized using the constant value 0, called the null
pointer that is, p points to nothing.
p = NULL; p = 0;
The number 0 is the only number that can be directly assigned to a
pointer variable.

13
Cont…

Pointers can be initialized to point to specific locations at the very


moment they are defined:
 int myvar;
 int * myptr = &myvar;
Pointers can be initialized either to the address of a variable (such as in
the case above), or to the value of another pointer (or array):
 int myvar;
 int *foo = &myvar;
 int *bar = foo;

14
Example

int x = 5;
int * numPtr=&x;
* numPtr = * numPtr * * numPtr ;
cout << x;
Another example.
int firstvalue, secondvalue;
int * mypointer;
mypointer = &firstvalue;
*mypointer = 10;
mypointer = &secondvalue;
*mypointer = 20;
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is15" << secondvalue << '\n';
Example

int firstvalue = 5, secondvalue = 15;


int * p1, * p2;
p1 = &firstvalue; // p1 = address of firstvalue
p2 = &secondvalue; // p2 = address of secondvalue
*p1 = 10; // value pointed to by p1 = 10
*p2 = *p1; // value pointed to by p2 = value pointed by p1
p1 = p2; // p1 = p2 (value of pointer is copied)
*p1 = 20; // value pointed by p1 = 20
cout << "firstvalue is " << firstvalue << '\n';
cout << "secondvalue is " << secondvalue << '\n';

16
Pointers and const

There are two places the const keyword can be placed within a pointer variable
declaration. This is because there are two different variables whose values you
might want to forbid changing: the pointer itself and the value it points to.
const int * ptr ;
 declares a changeable pointer to a constant integer. The integer value cannot be
changed through this pointer, but the pointer may be changed to point to a
different constant integer. int x=5; const int* ptr; ptr=&x; but
*ptr=20//impossible.
int * const ptr;
 declares a constant pointer to changeable integer data. The integer value can be
changed through this pointer, but the pointer may not be changed to point to a
different constant integer. int x; int *const ptr=&x; *p=90; but
ptr=&val//impossible.
const int * const ptr;
 forbids changing either the address ptr contains or the value it points to.
17
Pointers and const

Pointers can be used to access a variable by its address, and this access
may include modifying the value pointed.
 But it is also possible to declare pointers that can access the pointed value
to read it, or not to modify it.
int x;
int y = 10;
const int * p = &y;
x = *p; // ok: reading p
*p = x; // error: modifying p, which is const-qualified

18
Operations on Pointer Variables

The operations that are allowed on pointer variables are the assignment
and relational operations and some limited arithmetic operations.
 The value of one pointer variable can be assigned to another pointer
variable of the same type.
 Two pointer variables of the same type can be compared for equality,
and so on.
int *p, *q;
p = q;
p==q
p != q
To conduct arithmetical operations on pointers is a little different than to
conduct them on regular integer types. To begin with, only addition and
subtraction operations are allowed.
But both addition and subtraction have a slightly different behavior with
pointers, according to the size of the data type to which they19point.
Cont..

Binary operations between two Pointers


 Adding two pointers together is not allowed! But p+n valid statement
p+ n*sizeof p
 ptr1 - ptr 2 is allowed, as long as they are pointing to elements of the
same array. The result is ptr1 - ptr2
Pointer arithmetic can be very dangerous.
 Using pointer arithmetic, the program can accidentally access the
memory locations of other variables and change their content without
warning, leaving the programmer trying to find out what went wrong.
If a pointer variable tries to access either the memory spaces of other
variables or an illegal memory space, some systems might terminate the
program with an appropriate error message.

20
Cont…

int* p1,*p2;
cout<<p1+p2;//impossible
cout<<p1-p2;//possible
Logical Operations on Pointers
ptr1 > ptr2 is the same as ptr1 - ptr2 > 0,
ptr1 = ptr2 is the same as ptr1 - ptr2 = 0,
ptr1 < ptr2 is the same as ptr1 - ptr2 < 0,
if(p1>p2)//possible: true if memory address of p1 is greater than p2
Suppose now that we define three pointers in this compiler.
char *mychar; short *myshort; long *mylong;
They point to the memory locations 1000, 2000, and 3000, respectively.
++mychar; or mychar = mychar + 1; ++myshort; ++mylong;

21
Cont…

For example, let's imagine that in a given system, char takes 1


byte, short takes 2 bytes, and long takes 4.

22
Cont…

Regarding the increment (++) and decrement (--) operators, both can be
used as either prefix or suffix of an expression, with a slight difference in
behavior: as a
 prefix, the increment happens before the expression is evaluated, and
 suffix, the increment happens after the expression is evaluated.
postfix operators, such as increment and decrement, have higher
precedence than prefix operators, such as the dereference operator (*).

23
Cont…

The following expression:

 *p++

 is equivalent to *(p++). increase the value of p (so it now points to the next
element), but because ++ is used as postfix, the whole expression is evaluated
as the value pointed originally by the pointer (the address it pointed to before
being incremented).
Four possible combinations of the dereference operator with both the prefix and
suffix versions of the increment operator.
 *p++ // same as *(p++): increment pointer, and dereference un-incremented
address.
 *++p // same as *(++p): increment pointer, and dereference incremented address

 ++*p // same as ++(*p): dereference pointer, and increment the value it points to

 (*p)++ // dereference pointer, and post-increment the value it points to


24
Example

int listofnumber[]={1,5,8,13,15};
int *p;
p= listofnumber;
cout<<"*p++ increment pointer and dereference un-increment value “
<<*p++<<endl;
cout<<"*++p increment pointer, and dereference incremented
address“ <<*++p<<endl;
cout<<"++*p== dereference pointer, and increment the value it points to“
<<++*p<<endl;
cout<<"(*p)++==dereference pointer, and post-increment the value it
points to "<<(*p)++<<endl;
cout<<“After post Increment ”<<*p;

25
Pointers and Arrays

The concept of arrays is related to that of pointers.


In fact, arrays work very much like pointers to their first elements,
actually, an array can always be implicitly converted to the pointer of the
proper type. For example, consider these two declarations:
int myarray [20];
int * mypointer;
mypointer = myarray; valid statements.
myarray = mypointer; not valid statements.

26
Example

int numbers[5];
int * p;
p = numbers; *p = 10;
p++; *p = 20;
p = &numbers[2]; *p = 30;
p = numbers + 3; *p = 40;
p = numbers; *(p+4) = 50;
for (int n=0; n<5; n++)
cout << numbers[n] << ", ";

27
Pointers to pointers

C++ allows the use of pointers that point to pointers, in its turn, point to
data (or even to other pointers).
The syntax simply requires an asterisk (*) for each level of indirection in
the declaration of the pointer:
 char a;
 char * b;
 char ** c;
 a = 'z';
 b = &a;
 c = &b;
assuming the randomly chosen memory locations for each variable
of 7230, 8092, and 10502, could be represented as: variable c, which is a
pointer to a pointer. **c is of type char and a value of 'z‘.

28
Dynamic Variables

Variables that are created during program execution are called dynamic
variables.
With the help of pointers, C++ creates dynamic variables.
C++ provides two operators, new and delete, to create and destroy
dynamic variables, respectively.
When a program requires a new variable, the operator new is used. When
a program no longer needs a dynamic variable, the operator delete is used.

29
Operator new

operator new has two forms: one to allocate a single variable and another
to allocate an array of variables.
new dataType; to allocate a single variable
new dataType[intExp]; to allocate an array of variables
int *p; char *q;
p = new int;
q = new char[16];
The operator new allocates memory (a variable) of the designated type
and returns a pointer to it—that is, the address of this allocated memory.
Moreover, the allocated memory is uninitialized.
Because a dynamic variable is unnamed, it cannot be accessed directly.
It is accessed indirectly by the pointer returned by new.

30
Cont…

The statement:
p = &x;
Stores the address of x in p. However, no new memory is allocated. On
the other hand, consider the following statement:
p = new int;
 This statement creates a variable during program execution somewhere
in memory and stores the address of the allocated memory in p. The
allocated memory is accessed via pointer dereferencing—namely, *p.
Similarly, the statement:
q = new char[16];
 creates an array of 16 components of type char and stores the base
address of the array in q.

31
Cont..

32
Cont..

Recall that the operator new allocates memory space of a specific type
and returns the address of the allocated memory space.

However, if the operator new is unable to allocate the required memory


space (for example, there is not enough memory space), then it throws a
bad_alloc exception, and if this exception is not handled, it terminates the
program with an error message.

33
Cont..

p = new int; //Line 1


*p = 54; //Line 2
p = new int; //Line 3
*p = 73; //Line 4

34
Cont..

Now the obvious question is what happened to the memory space 1500 that p
was pointing to after execution of the statement in Line 1.
After execution of the statement in Line 3, p points to the new memory space at
location 1800.
The previous memory space at location 1500 is now inaccessible. In addition,
the memory space 1500 remains as marked allocated. In other words, it cannot
be reallocated. This is called memory leak.
 That is, there is an unused memory space that cannot be allocated.
What would happen if you executed statements, such as Line 3, a few thousand
or a few million times.
 There would be a good amount of memory leak. The program might then run
out of memory spaces for data manipulation and eventually result in an
abnormal termination of the program.
The question at hand is how to avoid memory leak. When a dynamic variable is
no longer needed, it can be destroyed; that
35 is, its memory can be deallocated.
Operator delete

The C++ operator delete is used to destroy dynamic variables. The syntax to
use the operator delete has two forms:
delete pointerVariable; //to deallocate a single dynamic variable
delete [] pointerVariable; //to deallocate a dynamically created array
 delete p;
delete [] name;
delete str;
deallocate the memory spaces that the pointers p, name, and str point
to.
Depending on a particular system, after these statements execute, these
pointer variables may still contain the addresses of the deallocated memory
spaces.
In this case, we say that these pointers are dangling to avoid this pitfall is to
set these pointers to NULL after the delete operation.
When a dynamic variable is no longer needed, it can be destroyed; that is, its
memory can be deallocated. 36
Cont…

Consider the following statements:


int *first;
int *second;
first = new int[10];
 The first two statements declare first and second pointer variables of
type int. The third statement creates an array of 10 components, and the
base address of the array is stored into first
delete [] first;
first = null;
After this statement executes, the array pointed to by first is deleted.

37
Dynamic array

One of the limitations of a static array is that every time you execute the
program, the size of the array is fixed, so it might not be possible to use the
same array to process different data sets of the same type.
One way to handle this limitation is to declare an array that is large enough
to process a variety of data sets.
However, if the array is very big and the data set is small, such a declaration
would result in memory waste.
On the other hand, it would be helpful if, during program execution, you
could prompt the user to enter the size of the array and then create an array of
the appropriate size.
This approach is especially helpful if you cannot even guess the array size.

38
Cont..

An array created during the execution of a program is called a dynamic


array.
To create a dynamic array, we use the second form of the new operator.
The statement:
int *p;
 declares p to be a pointer variable of type int.
The statement:
p = new int[10];
 allocates 10 contiguous memory locations, each of type int, and stores
the address of the first memory location into p.
In other words, the operator new creates an array of 10 components of
type int, it returns the base address of the array, and the assignment
operator stores the base address of the array into p.

39
Cont...

Thus, the statement:


*p = 25;
 stores 25 into the first memory location, and the statements:
p++; //p points to the next array component
*p = 35;//store 35 into the second memory location.
 C++ allows us to use array notation to access these memory locations.
 For example, the statements:
p[0] = 25;
p[1] = 35;
 store 25 and 35 into the first and second array components, respectively.
int *intList; //Line 1
int arraySize; //Line 2
cout << "Enter array size: "; //Line 3
cin >> arraySize; //Line 4
40
Example

What is the output of the following code fragment? The code is assumed
to be embedded in a correct and complete program.
int array_size = 10;
int *a;
a = new int[array_size];
int i;
for (i = 0; i < array_size; i++)
*(a + i) = i;
for (i = 0; i < array_size; i++)
cout << a[i] << " ";
cout << endl;

41
What is the output of the following C++ code?

int *first = new int;


int *second;
*first = 85;
second = first;
*second = *second + *first;
first = new int;
*first = *second - 100;
cout << *first << " " << *second << endl;

42
What is the output of the following C++ code?

double *firstPtr = new double; //Line 1


double *nextPtr = new double; //Line 2
*firstPtr = 62; //Line 3
nextPtr = firstPtr; //Line 4
delete firstPtr; //Line 5
delete nextPtr; //Line 6
firstPtr = new double; //Line 7
*firstPtr = 28; //Line 8
cout << *firstPtr << " " << *nextPtr << endl; //Line 9

43
What is the output of the following C++ code?

int *myList = new int[5];


int *yourList = new int[10];
myList[0] = 3;
for (int i = 1; i < 5; i++)
myList[i] = myList[i - 1] + i;
for (int i = 0; i < 5; i++){
yourList[i] = myList[i] + 4;
yourList[i + 5] = myList[4 - i] - 3;
}
cout << "myList: ";
for (int i = 0; i < 5; i++)
cout << myList[i] << " ";
cout << endl;
cout << "yourList: ";
for (int i = 0; i < 10; i++)
cout << yourList[i] << " ";
44

You might also like