Chapter-3-Pointers in CPP (1) Up

Download as pdf or txt
Download as pdf or txt
You are on page 1of 59

Pointers - C++

Variable address holders for dynamic memory manangment

Chapter 3- Pointers
Chapter Objectives
 Overview of pointers
 Declaration and assignment of pointers
 Pointers to pointers
 Pointer Arithmetic
 Arrays of Pointers
 Pointers and Arrays
 Dynamic Memory and Dynamic Arrays
 Array and Pointers in Functions
Chapter 3- Pointers in C++ 2
Pointers- Overview
 When we declare a variable we inform the compiler of two
things, the name of the variable and the type of the variable.
For example, we declare a variable of type integer with the
name k by writing:
int k;
On seeing the "int" part of this statement the compiler sets
aside 4 bytes of memory (on a PC) to hold the value of the
integer.
It also sets up a symbol table. In that table it adds the symbol
k and the relative address in memory where those 4 bytes
were set aside.
Chapter 3- Pointers in C++ 3
Pointers – Overview cont’d…
 Thus, later if we write:
 k = 2; we expect that, at run time when this statement is executed,
the value 2 will be placed in that memory location reserved for the
storage of the value of k.
 In C++ we refer to a variable such as the integer k as an "object".
 In a sense there are two "values" associated with the object k.
 One is the value of the integer stored there (2 in the above example)
and the other the "value" of the memory location, i.e., the address of k.
 But , sometimes we may be interested to have a variable that can hold
the address of another variable for so many reasons.
o Such as to have more control over the management of the computer’s memory, dynamic
arrays etc.
o Some data structures use pointers (e.g. linked list, tree).
Chapter 3- Pointers in C++ 4
Pointers – Overview Cont’d…
 Such a variable is called a pointer variable (for reasons which
hopefully will become clearer a little later).
 In C++ when we define a pointer variable we do so by preceding
its name with an asterisk *.
 In C++ we also give our pointer a type which, in this case, refers to
the type of data stored at the address we will be storing in our
pointer.
 For example, consider the variable declaration:
int y;
int *yptr; //ptr will store the address of an integer such as y
yptr=&y;
Chapter 3- Pointers in C++ 5
Operators in C++ Pointer
There are two pointer operators in C++:
o & the address of operator
o * the dereference operator
 The & literally mean “address of.” always produces the memory
address of whatever it precedes.
o Is also called the reference operator.
 The * operator, when used with pointers, either declares a
pointer or dereferences the pointer’s value.
 The dereference operator can be literally translated to "value
pointed by" .
Chapter 3- Pointers in C++ 6
C++ Pointer Operators Cont’d..
 Recall that a pointer is simply the address of an object in
memory.
 Hence, generally, objects can be accessed in two ways:
o directly by their symbolic name, or
o indirectly through a pointer.
 The act of getting to an object via a pointer to it, is called
dereferencing the pointer.

Chapter 3- Pointers in C++ 7


Un-initialized Pointer - Null pointer
 The pointer variable in “ int *ptr;” has no value, that is, we
have not stored an address in it in the declaration.
 If the declaration is outside of any function, it is initialized
to a value guaranteed in such a way that it is not pointing
to any C++ object or function.
 A pointer initialized in this manner is called a "null" pointer .
 The null pointer goes under the name NULL.
 Thus, setting the value of a pointer using the null pointer
we use NULL, as with an assignment statement
Chapter 3- Pointers in C++ 8
Null Pointers
 ptr = NULL;
guarantees that the pointer has become a null pointer.
 Similarly, just as one can test for an integer value of zero,
as in
 if(k == 0), we can test for a null pointer using

 if (ptr == NULL). //note uppercase

Chapter 3- Pointers in C++ 9


Declaring Pointers
 Is reserving a memory location for a pointer variable in the
heap.( compared with stack-frame)
 Syntax: Type_Name *variableName1, *variableName2, . . .;
 ???declare a pointer variable called p_age:
int * p_age;
 Whenever the dereference operator, *, appears in a variable
declaration, the variable being declared is always a pointer
variable.

Chapter 3- Pointers in C++ 10


Assigning values to pointers
 p_age is an integer pointer.The type of a pointer is very important.
 p_age can point only to integer values, never to floating-point or other
types.
 To assign p_age the address of a variable:
int age = 26; int * p_age; p_age = &age;
OR
int age = 26; int * p_age = & age;
 Two ways to print the value of age:
cout<<age;//prints value of age
cout<<*p_age;//dereferences p_age;

Chapter 3- Pointers in C++ 11


Assigning a value to a dereferenced pointer

A pointer must have a value before you can


dereference it (follow the pointer).

int *x; int foo;


*x=3; int *x;
x = &foo;
*x=3;

Chapter 3- Pointers in C++ 12


Pointers to void
 note that we can’t assign the address of a float type variable to an
integer pointer variable and similarly the address of an integer
variable can not be stored in a float or character pointer.
• flaot y;
• int x;
• int *ip;
• float *fp;
• ip = &y; //illegal statement
• fp = &x; //illegal statement

Chapter 3- Pointers in C++ 13


Pointers to void cont’d…
 Hence, we can assign the address of variable to pointer variable only if a variable
type is of the same type as the pointer. If both are different types, then we can’t
assign the address of variable to pointer variable.
 But there are ways in C++ to assign address of a variable to a pointer of a
different type by declaring pointer variable as a “void” as follows:
void *p;
int x;
float y;
p = &x; //valid assignment
p = &y; //valid assignment
 The difficulty on void pointers is that, void pointers can not be de
referenced. They are aimed only to store address and the dereference operator
is not allowed for void pointers.
Chapter 3- Pointers in C++ 14
Comparing Pointer Values
 int j = 5;
 int i = 5;
 int *ptrj1 = &j;
 int *ptrj2 = &j;
 int *ptri = &i;

 True/False:
o if (ptrj1 == ptrj2) ? True
o if (ptrj1 == ptri) ? False
o if (&ptrj1 == &ptrj2) ? False
o if (*ptrj1 == *ptri) ? True
Chapter 3- Pointers in C++ 15
Assignment operator in Pointers

Chapter 3- Pointers in C++ 16


Pointer Pitfalls
 Assigning values to uninitialized, null, or deleted pointers:

int *p; int *p = NULL; int *p = new int;


*p = 3; *p = 4; delete p;
*p = 5;

All of these cases end up with segmentation fault!

Chapter 3- Pointers in C++ 17


Dangling Pointer
 A pointer that points at nothing:
 Example:
int *p, *q;
p = new int;
q = p;
delete q; //memory for the dynamic variable re-claimed
*p = 3; //illegal assignment!

• p and q point to the same location, q is deleted, results with p becoming a


dangling pointer!

Chapter 3- Pointers in C++ 18


Dangling Pointer Cont’d…
 In the above example , both “p” and “q” would point to the
same dynamically allocated memory.
 The first destructor to execute would delete the dynamically
allocated memory, and the other object’s ptr would point to
memory that’s no longer allocated,
 This situation is called a dangling pointer

Chapter 3- Pointers in C++ 19


Pointers to pointers
x some int

int *x;
int **y; y some *int some int

double *z; z some double

Chapter 3- Pointers in C++ 20


Pointers to pointers
 Example:
o int i = 5;
o int *p_i = &i;
o int **pp_i = &p_i;
 Then:
pp_i is memory location of …
p_i
*pp_i is memory location of … ( dereferencing )
i
**pp_i equals…
5

Chapter 3- Pointers in C++ 21


Arrays of Pointers
 If you have to reserve many pointers for many different values,
you might want to declare an array of pointers.
int *iptr[10]; //reserves an array of 10 integer
pointers
 The above statement will create the following structure in RAM
??
iptr[4] = &age;// makes iptr[4] point to address of
age.
Chapter 3- Pointers in C++ 22
Pointers and Arrays
 The identifier of an array is equivalent to the address of its first
element, like a pointer is equivalent to the address of the first
element that it points to, so in fact they are the same thing.
 In C++, if ptr was a pointer wherever we might use
&var_name[0] we can replace that with var_name, thus in
our code where we wrote:
ptr = &my_array[0];
we can write:
ptr = my_array; .
Chapter 3- Pointers in C++ 23
Pointers and Arrays Cont’d…
 For example, given these two declarations:

int numbers[20];
int * p;
 the following allocation would be valid:

p = numbers;
Chapter 3- Pointers in C++ 24
Pointers and Arrays Cont’d…
 At this point p and numbers are equivalent and they have the
same properties, with the only difference that we could assign
another value to the pointer p whereas numbers will always point
to the first of the 20 numbers of type int with which it was defined.
 Therefore, although the previous expression was valid, the following
allocation is not:

numbers = p
 Because numbers is an array (constant pointer), and no values can
be assigned to constant identifiers.
Chapter 3- Pointers in C++ 25
Pointers and Arrays Cont’d…
 Array name is basically a const pointer pointing at the
beginning of the array.
 You can use the [ ] operator with pointers!
 Example:
o int A[5];
o Creates a memory block of 5 integers on the stack (5x4bytes) where
A (the pointer) points at the beginning of the array -> A[0]. (A = &A)
A
Chapter 3- Pointers in C++ 26
Pointers and Arrays Cont’d…

int *x;
int a[5]={-1,-2,-3,-4,-5};
x is “the address of a[2] ”
x = &a[2];
for (int i=0;i<3;i++)
x[i]++;
a x[i] is the same as a[i+2]
x
-1 -2 -3 -4 -5

x[0]
Chapter 3- Pointers in C++
x[1] x[2] 27
Array and pointers -Example

 Consider the following code  Note that n was an array


int n[5]={3,2,5,7,8}; name but used it like a
pointer and p_n was a
for ( int i=0; i<5; i++)
pointer but used it like an
cout<<(*n+i)<<endl; // vs array name.
cout<<*(n+i);
 Hence, array names are
int *p_n=n;
basically constant pointers
for( int j=0; j<5;j++)
cout<<p_n[j]<<" ";

CHAPTER 3- POINTERS IN C++ 28


Pointer arithmetic
• Integer math operations can be used with pointers: +, -, ++, --, +=, -=
• If you increment a pointer, it will be increased by the size of whatever it
points to.
• Incrementing pointers will basically make it point to the “next” element
in memory.
int *ptr = a;
*(ptr+2)
*(ptr+4)
*ptr

a[0] a[1] a[2] a[3] a[4]


int a[5];
Chapter 3- Pointers in C++ 29
Pointer Arithmetic Cont’d…
 since ptr++ is equivalent to
ptr + 1, incrementing a pointer using the unary ++
operator, increments the address it stores by the amount
sizeof(type) where "type" is the type of the object pointed
to. (e.g. 4 for an integer).
 Pointer arithmetic is meaningless unless performed on an array

Chapter 3- Pointers in C++ 30


Pointer Arithmetic Cont’d…

Chapter 3- Pointers in C++ 31


Pointer Arithmetic (Cont.)
 Example
Consider an integer array of 5 elements on a machine using 4 bytes for integers.
1000 1004 1008 1012 1016

V[0] V[1] V[2] V[3] V[4]

Pointer variable vPtr

- vPtr pointes to first element V[0] (location 1000)


i.e. vPtr = 1000
- vPtr +=2; sets vPtr to 1008
i.e. vPtr points to V[2]
Chapter 3- Pointers in C++ 32
Pointer arithmetic Cont’d…
 The following example show how pointer arithmetic works with pre and post
increment operators
 int *p= new int [3] {10,11,12}; // Note how a dynamic array is
initialized.
cout<<"*(p++)="<<*(p++); // post increment output=____

cout<<"*p="<<*p; //output=____
p++;
cout<<" *(++p)="<<*(++p); //pre increment output=____
cout<<" *p="<<*p; //output=___________________
Chapter 3- Pointers in C++ 33
Dynamic Memory Allocation- Application of Pointers
 Until now, in our programs, we have only had as much memory as
we have requested in declarations of variables, arrays and other
objects that we included, having the size of all of them to be fixed
before the execution of the program.
 But, What if we need a variable amount of memory that can only be
determined during the program execution (runtime)? For example,
in case that we need a user input to determine the necessary
amount of space.
 The answer is dynamic memory, for which C++ integrates the
operators new and delete.

Chapter 3- Pointers in C++ 34


Dynamic Memory Allocation- Cont’d…
 Pointers are useful for creating dynamic objects
during program execution.
o Unlike normal (global and local) objects which are
allocated storage on the runtime stack, a dynamic
object is allocated memory from a different storage
area called the heap.
o Dynamic objects do not obey the normal scope rules.
Their scope is explicitly controlled by the
programmer.
Chapter 3- Pointers in C++ 35
Variables in C++ Memory System
There are two "kinds" of memory available to a process:
 Stack:
o Stores local variables of the function.
o Removed once the function ends!
o Used by functions, global and local variables in C++

 Heap:
o Contains dynamically allocated variables.
o Stays once the function ends, unless cleared before(explicitly)!
o Used by pointers

Chapter 3- Pointers in C++ 36


Dynamic Memory – Cont’d…
 The New Operator
 In C++ new operator can create space dynamically i.e at run time,
and similarly delete operator is also available which releases the
memory taken by a variable and return memory to the operating
system.
 When the space is created for a variable at compile time this
approach is called static. If space is created at run time for a
variable, this approach is called dynamic.
 The new operator produces a new, nameless variable and returns a
pointer that points to this new variable
Chapter 3- Pointers in C++ 37
Dynamic Objects- The new Operator
 See the following two lines:
int a[10];//creation of static array- in the stack
int *a;
a = new int[10];//creation of dynamic array in the
heap
 Lets have another example:
int * ptr3;
ptr3 = new int [5];

Chapter 3- Pointers in C++ 38


Variables without any symbolic name

Consider the following code


p1 = new int; //p1 equal to the address of this new
variable (that is, p1 points to this new, nameless variable)
cin >> *p1;
*p1 = *p1 + 7; // what will *(p1+7) return?
cout << *p1;
Chapter 3- Pointers in C++ 39
Dynamic objects -the “new” operator
 // what is the difference between the variables in
c
int c=10; 10
Symbolically
named
p_c c variable (c)
int *p_c=&c; 10

 //and
p
int *p= new int; Nameless
p variable
*p=10; 10

Chapter 3- Pointers in C++ 40


Dynamic memory – Null pointer returned
 Dynamic memory allocation allows assigning memory during the
execution of the program using any variable, constant or
combination of both as size.
 Possibility that the memory may exhausted.
o a null pointer will be returned from the new Operator
int * ptr3;
ptr3 = new int [5];
if (ptr3 == NULL) {
// error assigning memory.Take measures.
}
 if ptr3 is NULL, it means that there is no enough memory location
in the heap to be given for ptr3

Chapter 3- Pointers in C++ 41


Dynamic Memory Allocation – Delete Operator
 Since the necessity of dynamic memory is usually limited to
concrete moments within a program, once this one is no longer
needed, it shall be freed so that it become available for future requests of
dynamic memory. For this, there exists the operator delete , whose form
is:
delete pointer_var ;
or
delete [] pointer_var ;
 The first expression should be used to delete memory allocated for a
single element, and the second one for memory allocated for multiple
elements (arrays).

Chapter 3- Pointers in C++ 42


Dynamic Memory – The “new” and “delete” Operators Examples

 Using the new keyword, we can


now
allocate memory on the heap.
 int *i = new int;
 string *str = new string(“hi there, heap is
cozy!”);  DO NOT DELETE A PONTER
 int *arr = new int[5]; NOT ALLOCATED BY “NEW”
 Deleting these objects can be
done by using the delete
keyword.
 delete i;
 delete str;
 delete[] arr;

CHAPTER 3- POINTERS IN C++ 43


Dynamic array - declaration, assignment, access, freeing memory
int x;
cout<<"Dynamic Array"<<endl;
cout<<“how many elements do you need?”<<endl;
cin>>x;
int *arr = new int[x];
for( int j=0;j<x;j++) //NOTE: range based for statement cannot be used in dynamic arrays
{
arr[j]=j+10;
cout<<(*arr+j)<<" "; // what will “cout<< *(arr+j)” will do? How are these two
different ?
}
delete [] arr;

Chapter 3- Pointers in C++ 44


Arrays and Pointers in Functions
 Arrays elements as parameters to function
 Indexed variables can be arguments to functions
o Example: If a program contains these declarations:
int i, n, a[10];
void my_function(int n);

Variables a[0] through a[9] are of type int, making


these calls legal:
my_function( a[ 0 ] );
my_function( a[ 3 ] );
my_function( a[ i ] );

Chapter 3- Pointers in C++ 45


Challenges in Array as Function Parameter
 The size needed for an array is changeable
o Often varies from one run of a program to another
o Is often not known when the program is written

 A common solution to the size problem


o Declare the array size to be the largest that could
be needed
o Decide how to deal with partially filled arrays
Chapter 3- Pointers in C++ 46
Partially Filled arrays
 When using arrays that are partially filled
o Functions dealing with the array may not need to
know the declared size of the array, only how many
elements are stored in the array
o A parameter, number_used, may be sufficient to
ensure that referenced index values are legal

Chapter 3- Pointers in C++ 47


Arrays as Function Arguments
 A formal parameter can be for an entire array
o Such a parameter is called an array parameter
• It is not a call-by-value parameter
• It is not a call-by-reference parameter
• Array parameters behave much like call-by-
reference
parameters

Chapter 3- Pointers in C++ 48


Arrays as Function Arguments
 An array parameter is indicated using empty
brackets in the parameter list such as

void fill_up(int a[ ], int size); // void fill_up(int [ ], int);

and if array score is declared this way:


int score[5], number_of_scores;

fill_up is called in this way:


fill_up(score, number_of_scores);

Chapter 3- Pointers in C++ 49


Arrays as Function Arguments cont’d…
 An array formal parameter is a placeholder for
the argument
o When an array is an argument in a function call,
an action performed on the array parameter is
performed on the array argument

o The values of the indexed variables can be changed


by the function

Chapter 3- Pointers in C++ 50


Array as function arguments Cont’d…
 What does the computer know about an array?
o The base type
o The address of the first indexed variable
o The number of indexed variables
 What does a function know about an array
argument?
o The base type
o The address of the first indexed variable
That is why we need a second parameter( size) in functions with array
parameters.

Chapter 3- Pointers in C++ 51


const Modifier to the parameters
 Array parameters allow a function to change the
values stored in the array argument
 If a function should not change the values of the
array argument, use the const modifier
 An array parameter modified with const is a
constant array parameter
o Example:
void show_the_world(const int a[ ], int size);

Chapter 3- Pointers in C++ 52


Using const modifier With Arrays
 If const is used to modify an array parameter:
o const is used in both the function declaration and
definition to modify the array parameter

o The compiler will issue an error if you write code


that changes the values stored in the array parameter

Chapter 3- Pointers in C++ 53


Function Calls and const
 If a function with a constant array parameter
calls another function using the const array
parameter as an argument…

o The called function must use a constant


array parameter as a placeholder for the array

o The compiler will issue an error if a function is


called that does not have a const array parameter to
accept the array argument

Chapter 3- Pointers in C++ 54


const Parameters Example
 double compute_average(int a[ ], int size);

void show_difference(const int a[ ], int size)


{
double average = compute_average(a, size);

}
 compute_average has no constant array parameter
 This code generates an error message because
compute_average could change the array parameter

Chapter 3- Pointers in C++ 55


Functions that return an array?
 A function may not return an array in the same way
that it returns a value of type int or double. int * getNumbers( )
 There is a way to obtain something more or less equivalent. {
 return a pointer to the array.
int r[10];
The main function may call the function on the right as follows

int *p;
for (int i = 0; i < 10; ++i) {
p = getNumbers(); r[i] = i+2;
for ( int i = 0; i < 10; i++ ) { cout << r[i] << endl;
cout << "*(p + " << i << ") : "; }
cout << *(p + i) << endl; return r;
}
}
CHAPTER 3- POINTERS IN C++ 56
Returning array of characters- another example
 The following code in the main can be  A function that returns a pointer
used to call the function. to nameless array of chars
int n;
cout<<"How many chars?"<<endl; char * getChars()
cin>>::n; {
char *chars=getChars(); char *p= new char[::n];
for (int y=0;y<::n;y++) for(int j=0;j<::n;j++)
{ {
cout<<*(chars+y)<<“ = "<<chars[y]<<endl; cin>>p[j];
} }
return p;
}
CHAPTER 3- POINTERS IN C++ 57
Pointers as function parameters
 We can also create functions that take a Int main ()
pointer as an argument {
Write a function that takes a pointer to an array int x;
of integers and returns the sum of the numbers cout<<"Dynamic Array"<<endl;
int sum ( int *p, int numvars ) cout<<"how many elements do you need?"<<endl;
{ cin>>x;
int sum=0; int *arr = new int[x];
for (int k=0; k<numvars; k++) for( int j=0;j<x;j++)
{
{
arr[j]=j+10;
sum+=*(p+k);
}
}
cout<<" The sum of the numbers/elements
return sum; created is="<<sum(arr,x);
} return 0;
}
CHAPTER 3- POINTERS IN C++ 58
The End

CHAPTER 3- POINTERS IN C++ 59

You might also like