0% found this document useful (0 votes)
18 views66 pages

2 Pointers

The document provides an overview of pointers in C++, including their declaration, memory management, and dynamic memory allocation. It discusses common errors associated with pointers, such as dangling pointers and memory leaks, and explains the relationship between pointers and arrays. Additionally, it covers pointer arithmetic, dereferencing, and accessing elements in one-dimensional and two-dimensional arrays using pointers.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views66 pages

2 Pointers

The document provides an overview of pointers in C++, including their declaration, memory management, and dynamic memory allocation. It discusses common errors associated with pointers, such as dangling pointers and memory leaks, and explains the relationship between pointers and arrays. Additionally, it covers pointer arithmetic, dereferencing, and accessing elements in one-dimensional and two-dimensional arrays using pointers.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 66

Pointers

(COMP-112)

Dr. Abdul Waheed Khan

Department of IT & Computer Science


PAF-IAST
From C++ Code to
Process
• C++ source files
• .cpp; .h
C++ source code
compiling
• Binary files
• .o binary files
linking
• Executable (linux, Ubuntu, …)
• a.out executable
running
• Process
• Managed by OS process
C++ Memory Models
• Common errors caused by poor memory management:
• Using a variable before it has been initialized
• Allocating memory for storage and not deleting it
• Using a value after it has been deleted
Introduction to Pointers
• When we declare a variable, some memory is allocated for
it.

• Thus, we have two properties for any variable:


1. Its Address
2. and its Data value

E.g., char ch = ‘A’; Memory Address Value

ch
311 65
Introduction to Pointers
• How to get the memory-address of a variable?

• Address of a variable can be accessed through the


referencing operator “&”
• Example: &i  will return memory location where
the data value for “i” is stored.

• A pointer is a variable, that stores an address.


Introduction to Pointers
• We can declare pointers as follows:
Type* <variable Name>;

• Example:
int* P;

- creates a pointer variable named “P”, that will


store address (memory location) of some int
type variable.
The address of Operator
&
• The & operator can be used to determine the
address of a variable, which can be assigned to a
pointer variable
• Examples:
Dereferencing Operator *
• C++ uses the * operator in yet another way with
pointers
• "The variable values pointed to by p"  *p
• Here the * is the dereferencing operator
p is said to be dereferenced
int v1=99;
int* p= &v1;
cout<<“ P points to the value: “<<*p;
Dereferencing Pointer
Example
int v1 = 0;
int* p1 = &v1; v1 and *p1 now refer to

*p1 = 42; the same address


cout << v1 << endl;
cout << *p1 << endl;

Output:
42
42
Pointer Assignment and
Dereferencing
• Assignment operator ( = ) is used to assign value of one
pointer to another

• Pointer stores addresses so p1=p2 copies an address


value into another pointer

int v1 = 55; Output:


int* p1 = &v1;
int* p2; 55
p2=p1; 55
cout << *p1 << endl;
cout << *p2 << endl;
Dynamic Memory Allocation
• Used when space requirements are
unknown at compile time

• Most of the time the amount of space


required is unknown at compile time

• Dynamic Memory Allocation (DMA):-


• With Dynamic memory allocation we can
allocate/delete memory (elements of an array)
at runtime or execution time.
Differences between Static and Dynamic
Memory Allocation

• Dynamically allocated memory is kept on the memory heap (also


known as the free store)

• Dynamically allocated memory cannot have a "name", it must be


referred to

• Declarations are used to statically allocate memory,


• the new operator is used to dynamically allocate memory
Dynamic Memory Allocation

• Heap management in C++ is explicit:


Memory Layout of C/C++
Program
0
• Typical memory representation of a C/C++ Program
text
Text Segment (instructions) – section in data
memory holds/contains executable instructions
Data Segment – contains the global and static bss
variables initialized by the programmer heap
BSS (Block Started by Symbol) Segment – AKA
Uninitialized Data Segment – contains
uninitialized global and static variables
Stack – contains temporary data like function
parameters, return addresses, local variables p
Heap – containing memory dynamically allocated
during program runtime stack
0xffffffff
Example
int main()
{
int *p;

p = new int; 0
*p = 99; text

data
return 0;
} bss

heap

0xffffffff stack
Example
int main()
{
int *p;

p = new int; 0
*p = 99; text

data
return 0;
} bss

heap

#@%*&

0xffffffff stack
Example
int main()
{
int *p;

p = new int; 0
*p = 99; text

data
return 0;
} bss

heap

99

0xffffffff stack
Aliasing
int main()
{
int *p, *q;

p = new int; 0
*p = 99; text
q = p; data

return 0; bss
}
heap

99

q
p

0xffffffff stack
Aliasing
int main()
{
int *p, *q;

p = new int; 0
*p = 99; text
q = p; data
*q = 88; bss

return 0; heap
}
88

q
p

0xffffffff stack
Aliasing
int main()
{
int *p, *q;

p = new int; 0
*p = 99; text
q = p; data
*q = 88; bss

delete q; heap

return 0; $%#^&
}

q
p

0xffffffff stack
Dangling Pointers
int main()
{
int *p, *q;

p = new int; 0
*p = 99; text
q = p;
P and q are dangling pointers data
*q = 88; WHY?
bss
delete q;
heap
*p = 77;
$%#^&
return 0;
}
q
p

0xffffffff stack
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
Avoiding a Dangling
Pointer

• For Variables:
delete v1;
v1 = NULL;

• For Arrays:
delete[ ] arr;
arr = NULL;
Returning Memory to the
Heap

• Remember:
• Return memory to the heap before undangling the pointer

• What's Wrong with the Following:


ptr = NULL;
delete ptr;
Memory Leaking
int main()
{
int *p;
p = new int;
// make the above space unreachable; How?
p = new int;

// even worse…; WHY?


while (1)
p = new int;
return 0;
}
Memory Leaking

void f ( )
{
int *p;
p = new int;
return;
}

int main ( )
{
f ( );
return 0;
}
Memory Leaks

• Memory leaks when it is allocated from the heap using the new
operator but not returned to the heap using the delete operator
Memory Leaking and Dangling
Pointers
• Dangling pointers and memory leaking are evil sources of
bugs:
• hard to debug
• may appear after a long time of run
• may be far from the bug point

• hard to prevent

• What should be the good programming practices while


using Pointers?
Pointers Data-Type
• Question:

Why is it important to declare the type of the variable that


a pointer points to?

Aren’t all memory addresses of the same length?


Pointers Type
• Answer:
- All memory addresses are of the same length,
• However, with operation “p++” where “p” is a
pointer  the compiler needs to know the data
type of the variable “p” (to jump at next memory
location)
• Examples:
• If “p” is a character-pointer then “p++” will
increment “p” by one byte (next location)
• if “p” is an integer-pointer its value on “p++”
would be incremented by 4 bytes (next loc.)
Null Address
• Like a local variable, a pointer is assigned a random value
(i.e., address) if not initialized
• 0 is a pointer constant that represents the empty or Null
address
• Should be used to avoid dangling pointers

• Cannot Dereference a Pointer whose value is Null:

int *ptr = 0; OR int *ptr=NULL;

cout << *ptr << endl; // ERROR: ptr


// does not point to
// a valid address
Relationship Between Pointers
and Arrays
• Arrays and pointers are closely related
• Array name is like constant pointer
• All arrays elements are placed in the consecutive
locations.
• Example:- int List [10]; List is the start address of
array

• Pointers can do array subscripting operations We


can access array elements using pointers.
• Example:- int value = List [2]; //value assignment
int* bPtr = List; //address assignment
Relationship Between Pointers and
Arrays (Cont.)
Effect:-
- List is an address, no need for &
- The bPtr pointer will contain the address of the first
element of array List.
• Element List[2] can be accessed by *( bPtr + 2 )
Relationship between Arrays and Pointers

• Arrays and pointers are closely related:

void main()
{
int numbers[]={10,20,30,40,50};
cout<<numbers[0]<<endl; 10
cout<<numbers<<endl; Address e.g., &34234
cout<<*numbers<<endl; 10
cout<<*(numbers+1); 20
}
Arrays and Pointers
Array name is the starting address of the array

• Let int A[25];


int *p; int i, j;

• Let p = A;

• Then p points to A[0]


p + i points to address of A[i]
&A[j] == p+j
*(p+j) is the same as A[j]
Arrays and Pointers
Pointer Arithmetic
Only two types of arithmetic operations allowed:
1) Addition : only integers can be added
2) Subtraction: only integers be subtracted

Which of the following are valid/invalid?


Comparing Pointers
• If one address comes before another address in
memory, the first address is considered less
than the second address.

• Two pointer variables can be compared using


C++ relational operators: <, >, <=, >=, ==

• In an array, elements are stored in consecutive


memory locations, E.g., address of Arr[2] will
be smaller than the address of Arr[3] etc.
Void Pointer
• void* is a pointer to no type at all:
• Any pointer type may be assigned to
void *

int iVar=5;
This is a great advantage…
float fVar=4.3; So, What are the limitations/cha
char cVar=‘Z’;
int* p1;
void* vp2;
p1 = &iVar; // Allowed
p1 = &fvar; // Not Allowed
P1 = &cVar; // Not Allowed
vp2 = &fvar; // Allowed
vp2 = &cVar; // Allowed
vp2 = &iVar; // Allowed
Accessing 1-Demensional Array
Using Pointers
• We know, Array name denotes the memory address of
its first slot. Address Data
• Example: 980 Element 0
int List [ 50 ]; 982 Element 1
int *Pointer; 984 Element 2
Pointer = List; 986 Element 3
988 Element 4
• Other slots of the Array (List [50]) can be accessed by
performing Arithmetic operations on Pointer. 990 Element 5
992 Element 6
• For example the address of (element 4 ) can be
th
994 Element 7
accessed using:-
996 Element 8
int *Value = Pointer + 3;
• The value of (element 4th) can be accessed using:- …
int Value = *(Pointer + 3); …
998 Element 49
Accessing 1-Demensional Array

Address Data
…. 980 Element 0
…. 982 Element 1
int List [ 50 ]; 984 Element 2
int *Pointer; 986 Element 3
293
Pointer = List; // Address of first Element 988 Element 4
990 Element 5
int *ptr; 992 Element 6
ptr = Pointer + 3; // Address of 4th 994 Element 7
Element 996 Element 8
*ptr = 293; // 293 value store at 4th

element address

} 998 Element 49
Accessing 1-Demensional Array
We can access all element of List [50] using
Pointers and for loop combinations. Address Data
980 Element 0

… 982 Element 1

… 984 Element 2

int List [ 50 ]; 986 Element 3

int *Pointer; 988 Element 4

Pointer = List; 990 Element 5

for ( int i = 0; i < 50; i++ ) 992 Element 6

{ 994 Element 7

cout << *Pointer; 996 Element 8

Pointer++; // Address of next …


element

}
998 Element 49
This is Equivalent to
for ( int loop = 0; loop < 50; loop++ )
cout << Array [ loop ] ;
Accessing 2-Demensional Array
• Note that the statements
int *Pointer; Address Data
Pointer = &List [3]; 980 Element 0

• represents that we are accessing the address 982 Element 1

of 4th slot. 984 Element 2


986 Element 3
988 Element 4
• In 2-Demensional array the statements 990 Element 5
int List[ 5 ][ 6 ]; 992 Element 6
int *Pointer; 994 Element 7
Pointer = &List [3]; 996 Element 8


Represents that we are accessing the address …
of 4th row 998 Element 50

• or the address the 4th row and 1st column.


Accessing 2-Demensional Array

• int List [ 9 ] [ 6 ]; Column


• int *ptr; 0 1 2 3 4 5

• ptr = &List [3]; 0 300 302 304 306 308 310


1 312 314 316 318 320 322
2 324 326 328 330 332 334
• To access the address of 4th row 2nd 3 336 338 340 342 344 346

Row
column: 4 348 350 352 354 356 358
5 360 362 364 366 368 370
• ptr++; // address of 4th row 2nd
6 372 374 376 378 380 382
column 7 384 386 388 390 392 394
• (faster than normal array accessing 8 396 398 400 402 404 406
Why?)
• Equivalent to List [3][1] ;
Memory address
Differences between Static and Dynamic
Memory Allocation

• Dynamically allocated memory is kept on the memory heap (also


known as the free store)

• Dynamically allocated memory cannot have a "name", it must be


referred to

• Declarations are used to statically allocate memory,


• the new operator is used to dynamically allocate memory
Returning Memory to the
Heap

• How Big is the Heap?


• Most applications request memory from the heap when they are running;

• It is possible to run out of memory (you may even have gotten a message like
"Running Low On Virtual Memory")

• So, it is important to return memory to the heap when you no longer need it
Casting pointers
Pointers have types, so you cannot just do

int *pi; double *pd;


pd = pi;

Even though they are both just integers, C++


not allows (Error)
Casting pointers

C++ will let you change the type of a pointer


with an explicit cast

int *pi; double *pd;


pd = (double*) pi;

Note: Values differenced after cast are


undermined (difference of memory size)
Creating Dynamic 2D Arrays
 Two basic methods:
1. Using a single Pointer
2. Using an Array of Pointers
Dynamic two dimensional arrays
1. Using a single Pointer
• Total elements in a 2D Array:
– m * n (i.e., rows * cols)

5 rows * 4 columns
= 20 elements

Target Approach=
• allocate 20 elements using dynamic allocation
• Use a single pointer to point and access those items.
Dynamic 2D Arrays
Dynamic 2D Array – Double Pointer
2. Using a Pointer that points to Array of Pointer
• Total elements in a 2D Array: M_rows * N_coulmns

Ptr2D
(Pointer to a Pointer)
Dynamic 2D Array – Double Pointer
Dynamic two
dimensional
arrays

Can we vary size of each


column in Dynamic 2D Array
(using double pointer)

PP  start of array of pointers


*PP  First Address pointed by first row (sub array)
*(*PP)  First value of first array
(*PP)++  Move to next address in the first array
PP++  Move to Next row (second array address
Dynamic 2D
Array
(Varying Row Size)
Constant Pointer
• A constant pointer is a pointer that is
constant, such that we cannot change the
location (address) to which the pointer
points to:

char c = 'c';
char d = 'd';
char* const ptr1 = &c;
ptr1 = &d; // Not Allowed

int* const ptrInt=&v1; //ptr is constant pointer to int


Pointer to Constant 1/2
• we cannot set a non-const pointer to a const data-item

const int value = 5; // value is const


int *ptr = &value; // compile error: cannot convert const int* to int*

*ptr = 6; // change value to 6

const int value = 5;


const int *ptr = &value; // this is okay,
*ptr = 6; // not allowed, we cannot change a const value
Pointer to Constant 2/2
• A pointer through which we cannot change the value
of variable it points is known as a pointer to constant.
• These type of pointers can change the address they
point to but cannot change the value kept at those
address.

int var1 = 0;
const int* ptr = &var1;
*ptr = 1; // Not Allowed
cout<<*ptr;
C-String and Char
Pointer
• A String: is simply defined as an array of characters
char* s;
// s is the address of the first character (byte) of the string

• A valid C string ends with the null character ‘\0’

• Direct initialization char* <string Literal>;

char* s=“PAF-IAST”;
cout<<s;
cout<<++s;
C-String and Char Pointer
C-String and Char Pointer - Example

// Copying string using Pointers

char* str1 = “Self-conquest is the greatest victory.”;


char str2[80]; //empty string
char* src = str1;
char* dest = str2;

while( *src ) //until null character,


*dest++ = *src++; //copy chars from src to dest

*dest = ‘\0’; //terminate dest

cout << str2 << endl; //display str2


Functions Pass by using
Reference Pointer
c
• Pass-by-reference with pointer arguments
• Use pointers as formal parameters
and addresses as actual parameters

• Pass address of argument using & operator


• Arrays not passed with & because
array name already an address
• Pointers variable are used inside
function
Pass by Reference Pointers– Example1
c

void func(int *num)


{
cout<<"num = "<<*num<<endl;
*num = 10;
cout<<"num = "<<*num<<endl;
}

void main()
{
int n = 5;
cout<<"Before call: n = "<<n<<endl;
func(&n);
cout<<"After call: n = "<<n<<endl;
}
Pass by Reference Pointers– Example2
c
void compDouble(int* Ar)
{
for(int i=0;i<10;i++)
{ *Ar=(*Ar)*2;
Ar++;
}
}
void main()
{ int Arr[10]={0,1,2,3,4,5,6,7,8,9};
compDouble(Arr);
for(int i=0;i<10;i++)
cout<<Arr[i]<<endl;
}
Pass by Reference Pointers– Example2
c
void compDouble(int* Ar)
{
for(int i=0;i<10;i++)
{ *Ar=(*Ar)*2;
Ar++;
}
}
void main()
{ int Arr[10]={0,1,2,3,4,5,6,7,8,9};
compDouble(Arr);
for(int i=0;i<10;i++)
cout<<Arr[i]<<endl;
}
Questions (last lecture)
c
Address of character variable…

You might also like