Object-Oriented Programming
Lecture 2A – Pointers
Ubaid Ur Rehman
ubaid.rehman@seecs.edu.pk
Outline
Pointer and Address Operators
Pointer Variables
Dereferencing
Pointers and Arrays
Pointer Arithmetic
Pointer as a Function Parameter
Allocation of Memory
Pointer and Address
Operators
Each variable in a program is stored at a unique
address in memory
Use the address operator “&” to get the address of
a variable:
int num = -23;
cout << # // prints address
// in hexadecimal
Pointer Variables
Pointer variables, which are often just called pointers,
are designed to hold memory addresses.
With pointer variables you can indirectly manipulate
data stored in other variables.
Each data type has its own pointer variable, pointer to
int, pointer to double, pointer to float.
C/C++ uses the address or address-of operator “&” to
get the address of a variable
C/C++ uses the indirection or contents-of or
dereference operator “*” to access the value of the
variable pointed by
Declaration of Pointer
Variables
A pointer variable is declared by:
dataType *pointerVarName;
The pointer variable pointerVarName is used to
point to a value of type dataType
The * before the pointerVarName indicates that
this is a pointer variable, not a regular variable
The * is not a part of the pointer variable name
Spacing in definition does not matter:
int * intptr;
int* intptr;
void* ptr;
Pointer Variables:
Example
int i; 0x1054
int *ptr; 17
ptr=&i;
cout << *ptr << endl;
Initializing Pointers
A pointer can be initialized during declaration by
assigning it the address of an existing variable
float data = 50.8;
float *ptr = &data;
If a pointer is not initialized during declaration, it
is wise to give it a NULL (0) value
int *ip = 0;
float *fp = NULL;
Benefit of Pointers
Working with memory locations that regular
variables don’t give you access to.
If several variables(objects/structs) need access to
another single variable two alternatives
Keep multiple copies of variable.
Share the data with each variable keeping a
reference to the needed data
Example
// This program stores the address of a variable in a pointer.
#include <iostream>
using namespace std;
int main()
{
int x = 25; //x is store on address 0x7e00
int *ptr;
ptr = &x; // Store the address of x in ptr
cout << "The value in x is " << x << endl;
cout << "The address of x is " << ptr << endl;
}
Example: Output
The value in x is 25
The address of x is 0x7e00
x
25
ptr
0x7e00
Address of x: 0x7e00
Exercise
// This program demonstrates the use of the indirection
operator.
#include <iostream>
using namespace std;
int main()
{
int x = 25;
int *ptr;
ptr = &x; // Store the address of x in ptr
cout << "Here is the value in x, printed twice:\n";
cout << x << " " << *ptr << endl;
*ptr = 100;
cout << "Once again, here is the value in x:\n";
cout << x << " " << *ptr << endl;
}
Exercise: Output
Here is the value in x, printed twice:
25 25
Once again, here is the value in x:
100 100
Dereferencing
Dereferencing – Using a pointer variable to
access the value stored at the location pointed
by the variable
Provide indirect access to values and also called
indirection
Done by using the dereferencing operator * in
front of a pointer variable
Dereferencing: Example
#include <iostream>
using namespace std; ptr FFF0 FFF4
void main()
{ FFF1
float data = 50.8; FFF2
float *ptr;
FFF3
ptr = &data;
cout << ptr << *ptr << endl; data FFF4 50.8
*ptr = 27.4; FFF5
cout << *ptr << endl;
cout << data << endl; FFF6
}
Output:
Dereferencing: Example
#include <iostream>
using namespace std; ptr FFF0 FFF4
void main()
{ FFF1
float data = 50.8; FFF2
float *ptr;
FFF3
ptr = &data;
cout << ptr << *ptr << endl; data FFF4 50.8
*ptr = 27.4; FFF5
cout << *ptr << endl;
cout << data << endl; FFF6
}
Output:
FFF450.8
Dereferencing: Example
#include <iostream>
using namespace std; ptr FFF0 FFF4
void main()
{ FFF1
float data = 50.8; FFF2
float *ptr;
FFF3
ptr = &data;
cout << ptr << *ptr << endl; data FFF4 27.4
*ptr = 27.4; FFF5
cout << *ptr << endl;
cout << data << endl; FFF6
}
Output:
Dereferencing: Example
#include <iostream>
using namespace std;
void main() ptr FFF0 FFF4
{ FFF1
float data = 50.8;
float *ptr; FFF2
ptr = &data; FFF3
cout << ptr << *ptr << endl;
*ptr = 27.4; data FFF4 27.4
cout << *ptr << endl; FFF5
cout << data << endl;
FFF6
}
Output:
FFF450.8
27.4
Dereferencing: Example
#include <iostream>
using namespace std;
void main() ptr FFF0 FFF4
{ FFF1
float data = 50.8;
float *ptr; FFF2
ptr = &data; FFF3
cout << ptr << *ptr << endl;
*ptr = 27.4; data FFF4 27.4
cout << *ptr << endl; FFF5
cout << data << endl;
FFF6
}
Output: FFF450.8
27.4
27.4
Pointers and Arrays
Array name can be used as a pointer constant
int vals[] = {4, 7, 11};
cout << *vals; // displays 4
Pointer can be used as an array name
int *valptr = vals;
cout << valptr[1]; // displays 7
Pointers in Expressions
Given:
int vals[]={4,7,11};
int *valptr = vals;
What is valptr + 1?
It means (address in valptr) + (1 * size of an int)
cout << *(valptr+1); // displays 7
cout << *(valptr+2); // displays 11
Must use ( ) in expression
Example
// This program shows an array name being dereferenced
with the * operator.
#include <iostream>
using namespace std;
int main()
{
short numbers[] = {10, 20, 30, 40, 50};
cout << "The first element of the array is ";
cout << *numbers << endl;
}
Example: Output
The first element in the array is 10
numbers[0] numbers[1] numbers[2] numbers[3] numbers[4]
numbers
Exercise
// This program processes the contents of an array. Pointer
notation is used.
#include <iostream>
using namespace std;
int main()
{
int numbers[5];
cout << "Enter five numbers: ";
for (int count = 0; count < 5; count++)
cin >> *(numbers + count);
cout << "Here are the numbers you entered:\n";
for (int count = 0; count < 5; count++)
cout << *(numbers + count)<< " ";
cout << endl;
}
Exercise: Output
Enter five numbers: 5 10 15 20 25
Here are the numbers you entered:
5 10 15 20 25
numbers[0] numbers[1] numbers[2] numbers[3] numbers[4]
numbers (numbers+1) (numbers+2) (numbers+3) (numbers+4)
Pointer Arithmetic
Some mathematical operations may be performed
on pointers.
The ++ and -- operators may be used to increment
or decrement a pointer variable.
An integer may be added to or subtracted from a
pointer variable. This may be performed with the
+, - , +=, or -=, operators.
A pointer may be subtracted from another pointer.
Pointer Arithmetic
Assume the variable definitions
int vals[] = {4,7,11};
int *valptr = vals;
Example of pointer subtraction
valptr += 2;
cout << valptr - vals;
This statement prints 2: the number of ints
between valptr and vals
Example
// This program uses a pointer to display the contents of an integer array.
#include <iostream>
using namespace std;
int main()
{
int set[8] = {5, 10, 15, 20, 25, 30, 35, 40};
int *nums, index;
nums = set;
cout << "The numbers in set are:\n";
for (index = 0; index < 8; index++)
{
cout << *nums << " ";
nums++;
}
cout << "\nThe numbers in set backwards are:\n";
for (index = 0; index < 8; index++)
{
nums--;
cout << *nums << " ";
}
}
Example: Output
The numbers in set are:
5 10 15 20 25 30 35 40
The numbers in set backwards are:
40 35 30 25 20 15 10 5
Pointers as a Function
Parameters
A pointer can be used as a function parameter. It
gives the function access to the original argument,
much like a reference parameter does.
Requires:
asterisk * on parameter in prototype and heading
void getNum(int *ptr);
asterisk * in body to dereference the pointer
cin >> *ptr;
address as argument to the function
getNum(&num);
Example
// This program uses two functions // Definition of getNumber. The
that accept addresses of parameter, Input, is a pointer.
variables as arguments. // This function asks the user for a
#include <iostream> number. The value entered
using namespace std; // is stored in the variable pointed to by
Input.
// Function prototypes
void getNumber(int *); void getNumber(int *input)
void doubleValue(int *); {
cout << "Enter an integer number: ";
cin >> *input;
int main() }
{
int number; // Definition of doubleValue. The
getNumber(&number); // Pass parameter, val, is a pointer.
address of number to // This function multiplies the variable
getNumber pointed to by val by
doubleValue(&number); // and // two.
doubleValue.
cout << "That value doubled is void doubleValue(int *val)
" << number << endl; {
} *val *= 2;
}
Example: Output
Enter an integer number: 10
That value doubled is 20
Allocation of Memory
Static Allocation: Allocation of memory space at
compile time.
Dynamic Allocation: Allocation of memory space
at run time.
Dynamic Memory Allocation
Pointers need to be used for dynamic allocation of
memory:
new, dynamically allocate space
delete, later free this space
The new Operator
If memory is available, the new operator allocates
memory space for the requested object/array, and
returns a pointer to (address of) the memory
allocated.
If sufficient memory is not available, the new
operator returns NULL.
The dynamically allocated object/array exists until
the delete operator destroys it.
The delete Operator
The delete operator deallocates the object or array
currently pointed to by the pointer which was
previously allocated at run-time by the new
operator.
the freed memory space is returned to Heap
the pointer is then considered unassigned
If the value of the pointer is NULL there is no
effect.
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4
0EC5
0EC6
0EC7
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0 0EC4
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4
0EC5
0EC6
0EC7
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0 0EC4
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4 22
0EC5
0EC6
0EC7
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0 0EC4
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4 22
Output:
0EC5
22 0EC6
0EC7
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0 ?
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4
0EC5
0EC6
0EC7
Dynamic Memory Allocation:
Example
int *ptr; ptr FDE0 0
ptr = new int; FDE1
*ptr = 22; FDE2
cout << *ptr << endl;
FDE3
delete ptr;
ptr = NULL;
0EC4
0EC5
0EC6
0EC7
Dynamic Memory Allocation
Dynamic allocation is useful when
Arrays need to be created whose extent is not
known until run time
Complex structures of unknown size and/or shape
need to be constructed as the program runs
Objects need to be created and the constructor
arguments are not known until run time