Pointer
- Pointer points the location of a variable, it means it tells address of an address.
- A pointer is a variable that holds a memory address, usually the location of another variable in memory.
Pointer |
Defining a Pointer Variable
int *iptr;
OR,
int *p;
OR,
int* p;
OR,
int *p;
OR,
int* p;
- iptr can hold the address of an int
Address in C++(Pointer)
#include <iostream.h>
#include <conio.h>
int main()
{
int var1 = 3;
int var2 = 24;
int var3 = 17;
cout << &var1 << endl;
cout << &var2 << endl;
cout << &var3 << endl;
}
Expected Output:-
0x7fff5fbff8ac
0x7fff5fbff8a8
0x7fff5fbff8a4
C++ Program to understand the working of pointer.
#include <iostream.h>
#include <conio.h>
int main() {
int *pc, c;
c = 5;
cout << "Address of c (&c): " << &c << endl;
cout << "Value of c (c): " << c << endl << endl;
pc = &c; // Pointer pc holds the memory address of variable c
cout << "Address that pointer pc holds (pc): "<< pc << endl;
cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;
c = 11; // The content inside memory address &c is changed from 5 to 11.
cout << "Address pointer pc holds (pc): " << pc << endl;
cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;
*pc = 2;
cout << "Address of c (&c): " << &c << endl;
cout << "Value of c (c): " << c << endl << endl;
return 0;
}
Expected Output:-
Address of c (&c): 0x7fff5fbff80c
Value of c (c): 5
Address that pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 5
Address pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 11
Address of c (&c): 0x7fff5fbff80c
Value of c (c): 2
Memory layout
#include <iostream.h>
#include <conio.h>
int main()
{
int var1 = 3;
int var2 = 24;
int var3 = 17;
cout << &var1 << endl;
cout << &var2 << endl;
cout << &var3 << endl;
}
Expected Output:-
0x7fff5fbff8ac
0x7fff5fbff8a8
0x7fff5fbff8a4
C++ Program to understand the working of pointer.
#include <iostream.h>
#include <conio.h>
int main() {
int *pc, c;
c = 5;
cout << "Address of c (&c): " << &c << endl;
cout << "Value of c (c): " << c << endl << endl;
pc = &c; // Pointer pc holds the memory address of variable c
cout << "Address that pointer pc holds (pc): "<< pc << endl;
cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;
c = 11; // The content inside memory address &c is changed from 5 to 11.
cout << "Address pointer pc holds (pc): " << pc << endl;
cout << "Content of the address pointer pc holds (*pc): " << *pc << endl << endl;
*pc = 2;
cout << "Address of c (&c): " << &c << endl;
cout << "Value of c (c): " << c << endl << endl;
return 0;
}
Expected Output:-
Address of c (&c): 0x7fff5fbff80c
Value of c (c): 5
Address that pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 5
Address pointer pc holds (pc): 0x7fff5fbff80c
Content of the address pointer pc holds (*pc): 11
Address of c (&c): 0x7fff5fbff80c
Value of c (c): 2
Memory layout
To access num using iptr and indirection operator *
cout << iptr; // prints 0x4a00
cout << *itptr; // prints 25
Similary, following declaration shows:
char *cptr;
float *fptr;
cptr is a pointer to character and fptr is a pointer to float value.
Pointer Arithmetic
Some arithmetic operators can be used with pointers:
- Increment and decrement operators ++, --
- Integers can be added to or subtracted from pointers using the operators +, -, +=, and -=
- Each time a pointer is incremented by 1, it points to the memory location of the next element of its base type.
- If “p” is a character pointer then “p++” will increment “p” by 1 byte.
- If “p” were an integer pointer its value on “p++” would be incremented by 2 bytes.
Pointers and Arrays
Array name is base address of array
int vals[] = {4, 7, 11};
cout << vals; // displays 0x4a00
cout << vals[0]; // displays 4
Lets takes an example:
int arr[]={4,7,11};
int *ptr = arr;
What is ptr + 1?
It means (address in ptr) + (1 * size of an int)
cout << *(ptr+1); // displays 7
cout << *(ptr+2); // displays 11
Array Access
Array notation arr[i] is equivalent to the pointer notation *(arr + i)
Assume the variable definitions
int arr[]={4,7,11};
int *ptr = arr;
Examples of use of ++ and --
ptr++; // points at 7
ptr--; // now points at 4
C++ Program to display address of elements of an array using array and pointers
#include <iostream.h>
#include <conio.h>
int main()
{
float arr[5];
float *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;
cout<<"\nDisplaying address using pointers: "<< endl;
for (int i = 0; i < 5; ++i)
{
cout << "ptr + " << i << " = "<< ptr + i << endl;
}
return 0;
}
Expected Output:-
Displaying address using arrays:
&arr[0] = 0x7fff5fbff880
&arr[1] = 0x7fff5fbff884
&arr[2] = 0x7fff5fbff888
&arr[3] = 0x7fff5fbff88c
&arr[4] = 0x7fff5fbff890
Displaying address using pointers:
ptr + 0 = 0x7fff5fbff880
ptr + 1 = 0x7fff5fbff884
ptr + 2 = 0x7fff5fbff888
ptr + 3 = 0x7fff5fbff88c
ptr + 4 = 0x7fff5fbff890
C++ Program to display address of elements of an array using array and pointers
#include <iostream.h>
#include <conio.h>
int main()
{
float arr[5];
float *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;
cout<<"\nDisplaying address using pointers: "<< endl;
for (int i = 0; i < 5; ++i)
{
cout << "ptr + " << i << " = "<< ptr + i << endl;
}
return 0;
}
Expected Output:-
Displaying address using arrays:
&arr[0] = 0x7fff5fbff880
&arr[1] = 0x7fff5fbff884
&arr[2] = 0x7fff5fbff888
&arr[3] = 0x7fff5fbff88c
&arr[4] = 0x7fff5fbff890
Displaying address using pointers:
ptr + 0 = 0x7fff5fbff880
ptr + 1 = 0x7fff5fbff884
ptr + 2 = 0x7fff5fbff888
ptr + 3 = 0x7fff5fbff88c
ptr + 4 = 0x7fff5fbff890
C++ Memory Map
Once a program is compiled, C++ creates four logically distinct regions of memory:
- Code Area : Area to hold the compiled program code
- Data Area : Area to hold global variables
- Stack Area : Area to hold the return address of function calls, argument passed to the functions, local variables for functions and the current state of the CPU.
- Heap : Area from which the memory is dynamically allocated to the program.
Accessing address of a variable
- Computer’s memory is organized as a linear collection of bytes.
- Every byte in the computer’s memory has an address.
- Each variable in program is stored at a unique address.
- We can use address operator & to get address of a variable:
int num = 23;
cout << # // prints address in hexadecimal
Character Pointers and Strings
Initialize to a character string.
char* a = “Hello”;
- A is pointer to the memory location where ‘H’ is stored. Here “a” can be viewed as a character array of size 6, the only difference being that a can be reassigned another memory location.
char* a = “Hello”;
a gives address of ‘H’
*a gives ‘H’
a[0] gives ‘H’
a++ gives address of ‘e’
*a++ gives ‘e’
Pointers as Function Parameters
- A pointer can be a parameter. It works like a reference parameter to allow change to argument from within function.
Pointers as Function Parameters
void swap(int *x, int *y)
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
swap(&num1, &num2);
Program to show Passing by reference without pointers
#include <iostream.h>
#include <conio.h>
// Function prototype
void swap(int&, int&);
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a, b);
cout << "\nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int& n1, int& n2) {
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
Expected Output:-
Before swapping
a = 1
b = 2
After swapping
a = 2
b = 1
Program to show Passing by reference without pointers
#include <iostream.h>
#include <conio.h>
// Function prototype
void swap(int&, int&);
int main()
{
int a = 1, b = 2;
cout << "Before swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
swap(a, b);
cout << "\nAfter swapping" << endl;
cout << "a = " << a << endl;
cout << "b = " << b << endl;
return 0;
}
void swap(int& n1, int& n2) {
int temp;
temp = n1;
n1 = n2;
n2 = temp;
}
Expected Output:-
Before swapping
a = 1
b = 2
After swapping
a = 2
b = 1
Pointers to Constants and Constant Pointers
- Pointer to a constant: cannot change the value that is pointed at
- Constant pointer: address in pointer cannot change once pointer is initialized
Pointers to Structures
We can create pointers to structure variables
struct Student {int rollno; float fees;};
Student stu1;
Student *stuPtr = &stu1;
(*stuPtr).rollno= 104;
-or-
Use the form ptr->member:
stuPtr->rollno = 104;
Static allocation of memory
- The sum of memory to be allocated is estimated in the static memory allocation and is pre-known.
- This memory will be allocated during the construct itself.
- All the declared variables declared to be natural are dynamically allocated to memory.
Dynamic allocation of memory
- The amount of memory to be reserved is not specified in the dynamic memory allocation.
- This memory is allocated as and when needed during runtime.
- Using new operator, the memory is dynamically allocated.
Free store
- Free store is a pool of un-allocated heap memory provided to a program which the program uses during execution for dynamic allocation.
Dynamic Memory Allocation
- We can allocate storage for a variable while program is running by using new operator
To allocate memory of type integer
int *iptr=new int;
To allocate array
double *dptr = new double[25];
To allocate dynamic structure variables or objects
Student sptr = new Student; //Student is tag name of structure
Releasing Dynamic Memory
Use delete to free dynamic memory
delete iptr;
To free dynamic array memory
delete [] dptr;
To free dynamic structure
delete Student;
Memory Leak
- If the objects, which are dynamically allocated memory, are not removed using delete, the memory block will remain occupied even at the end of the program.
- Such blocks of memory are known as orphaned blocks of memory.
- Such orphaned blocks of memory carry adverse effects on the system when the number increases.
- This condition is called memory leak.
Self Referential Structure
- The self referential structures are structures that include an element that is a pointer to another structure of the same type.
struct node
{
int data;
node* next;
}