Pointers in C++

Pointers

Address: Each variable is assigned with a unique memory location(16bit)by the compiler for access and identification.

  • Pointer definition: A pointer is a variable that stores the address of another variable.
  • The values stored in this pointer can be the address of an ordinary variable, array variable or another pointer variable.
pointer in c++
Pointer in c++

 

The address and pointers work by using two operators Addressof (&) and indirection or dereference (*) operator

Declaring and initializing pointers 

data_type *var_name;
*var_name=<&any_var>;
Example:-
int k=5;
int *a;//declaring pointer
a=&k;//initialising pointer

C++ program to demonstrate pointers and address

#include<iostream>
using namespace std;
main()
{
int a=20;
int *ptr;//pointer declartion
ptr=&a;//pointer initilisation
cout<<"value of a:"<<a<<endl;// gives 20 i.e a's value
cout<<"address of a:"<<&a<<endl;//a's address
cout<<"value of *ptr:"<<*ptr<<endl;//pointing to address of 'a' i.e gives value at a's adress
cout<<"value of *&a:"<<*(&a)<<endl;//* ptr is interpreteed as *&a
cout<<"value of ptr:"<<ptr<<endl;// ptr gives a's adress as it is initialised with a's adress
cout<<"address of ptr:"<<&ptr<<endl;//gives ptr adress
}

O/P

value of a:20
address of a:0x6ffe40
value of *ptr:20
value of *&a:20
value of ptr:0x6ffe40
address of ptr:0x6ffe44

Advantages of pointer:

  • Dynamic memory allocation
  • Improves execution speed
  • handle arrays, strings, structures in functions
  • To manage data structures
  • They play a key role in the design of Operating systems

Disadvantages:

They are not secured as they are directly working on address

Competitive Coding Techniques

Pointers to pointers:

  • In order to store the address of the pointer variable itself, we require another a pointer called double pointer
  • To store the address of double pointer We store it in another pointer variable called triple pointer and so on, this can be extended any level

Creating Double and Triple Pointers

#include<iostream>
using namespace std;
main()
{
int a=25;
int *p=&a;//normal pointer
int **p2=&p;//double pointer stores pointer address i.e p's addres
int ***p3=&p2;//triple pointer stores address of double pointer i.e p3's address
cout<<"a value is :"<<a<<endl;
cout<<"a value using p:"<<*p<<endl;
cout<<"a value using p2:"<<**p2<<endl;
cout<<"a value using p3:"<<***p3<<endl;
}

O/P:-

a value is :25 
a value using p:25
a value using p2:25
a value using p3:25

How it works:

  • given a=25, assume a’s and p’s addresses are 2000 and 3000 respectively.
  • *p=*(&a)=*(2000)=25
  • **p2=*(*p2)=*(*(&p))=*(*(3000))=*((2000))=25

as p points a’s address, p2 contains the address of p, pointing to p2 gives P’s’address, again pointing to P’s address gives a’s’ address and finally pointing a’s address gives a’s value

Competitive Coding Techniques

Using Pointers in Arrays

By assigning the base cell address of an array to a pointer we can access the array elements using the following notation

*(baseadress+index*sizeof(array_type))

Example:
int a[5]={9,7,3,5,2}
int *ptr=&a[0]//assigning staring adress and incerementing
  • Assume base address is 2000
    a[0]=*(2000+0*4)=*(2000+0)=*(2000)=9
    a[1]=*(2 array  000+1*4)=*(2000+4)=*(2004)=7
    Suppose, the pointer needs to point to the fourth element of an array, that is, hold the address of fourth array element in the above case.
  • Since ptr points to the third element in the above example, ptr + 1 will point to the fourth element.
  • You may think, ptr + 1 gives you the address of next byte to the ptr. But it’s not correct.This is because pointer ptr is a pointer to an int and size of it is fixed for an operating system (size of it is 4 byte of the 64-bit operating system).
  • Hence, the address between ptr and ptr + 1 differs by 4 bytes. If pointer ptr was a pointer to char then, the address between ptr and ptr + 1 would have differed by 1 byte since the size of a character is 1 byte.

C++ Program to display address of elements of an array using both array and pointers

#include<iostream>
using namespace std;
int main()
{
int arr[5]={1,2,3,4,5};
int *ptr;
cout << "Displaying address using arrays: " << endl;
for (int i = 0; i < 5; ++i)
{
cout << "&arr[" << i << "] = " << &arr[i] << endl;
}
// ptr = &arr[0]
ptr = arr;//assiing base address to pointer

cout<<"\nDisplaying address using pointers: "<< endl;
for (int i = 0; i < 5; ++i)
{
cout << "ptr + " << ptr + i << " = "<< *(ptr+i) << endl;//access by incerementing address
}
return 0;
}

Output

Displaying address and values using arrays:
&arr[0x7fff5fbff880] = 1
&arr[0x7fff5fbff884] = 2
&arr[0x7fff5fbff888] = 3
&arr[0x7fff5fbff88c] = 4
&arr[0x7fff5fbff890] = 5

Displaying address using pointers:
ptr + 0 = 0x7fff5fbff880
ptr + 1 = 0x7fff5fbff884
ptr + 2 = 0x7fff5fbff888
ptr + 3 = 0x7fff5fbff88c
ptr + 4 = 0x7fff5fbff890

Wild/Bad pointers

  • A pointer which just declared but not initialized with any address is called wild pointer
  • They point to some arbitrary memory location that and may be used by the system and cause a program to crash or behave badly.
  • This problem can be solved using null pointers

Example

void main()
{
int *p;//declartion but no initialisation
cout<<"*p="<<*p<<"\n";//junk
cout<<"p="<<p<<"\n";//gives an arbitraryaddresss that is reserved already
}

Null Pointer

  • It is always a good practice to assign the pointer NULL to a pointer variable at the declaration case you do not have an address to be assigned.
  • A pointer that is assigned NULL is called a null pointer.
  • The NULL pointer is a constant with a value of zero, defined in several standard libraries, including iostream.
  • Many times, uninitialized variables hold some junk values and it becomes difficult to debug the program.

Example

int main () 
{
int *ptr = NULL;//inilialising with NULL
cout << "The value of ptr is " << ptr ;
return 0;
}

O/P

The value of ptr is 0
  • On most of the operating systems, programs are not permitted to access memory at address 0 because that memory is reserved by the operating system.
  • But by convention, if a pointer contains the null (zero) value, it is assumed to point to nothing.

Void Pointer

  • Generally, Pointers are type specific i.e a pointer of integer type can hold the address of an integer variable only, It some times may cause problems if by mistake if we assign a pointer variable to a different datatype
  • Hence a Void pointer is a Generic Pointer that can point to any datatype object, provided it must be typecasted while accessing so as compiler should the required number of bytes for that value
  • If a pointer’s type is void *, the pointer can point to any variable that is not declared with the const or volatile keyword.

Example

main()
{
int a=10;
float b=1.5;
void *p=&b;//pointing to float variable address
//int *c=&b//invalid types c must be float pointer
cout<<"b value:"<<*(float *)p;
}

O/P

b value:1.5

Dangling pointer

  • A pointer that is still pointing to a memory address that has been deleted is called dangling pointer
  • To over this null pointers can be used

Example:

main()
{
int *p=new int(100);//allocating memory
cout<<"*p="<<*p<<endl;
cout<<"p="<<p<<endl;
delete p;// adress in p is no more
cout<<"p value="<<*p<<endl;//garbage value
p=NULL;//point no where
cout<<"p value="<<*p<<endl;
}

Practice Example on Pointers

#include<iostream>
using namespace std;
main()
{
int a=25;
int *p=&a;//single step declartion and initialisation
cout<<a<<*p;
a=45;//*p also changes 
cout<<a<<*p;
a=66;
cout<<a<<*p;
}