Introduction to Pointers
Pointer is a variable which points to the address of another variable.
Consider the declaration,
int i = 3 ;
This declaration tells the C compiler to:
(a) Reserve space in memory to hold the integer value.
(b) Associate the name i with this memory location.
(c) Store the value 3 at this location.
address of operator(&)--The expression &i returns the address of the variable i,
value at address operator(*)
It gives the value stored at a particular address.
The ‘value at address’ operator is also called ‘indirection’ operator.
main( )
{
int i = 3 ;
printf ( "\nAddress of i = %u", &i ) ;
printf ( "\nValue of i = %d", i ) ;
printf ( "\nValue of i = %d", *( &i ) ) ;
}
Output:
Address of i = 65524
Value of i = 3
Value of i = 3
Pointer arithmetic
DVNR/IT/C/Pointers Page 1
The arithmetic operations that we can use on pointers:
Adding an integer to, or subtracting an integer from, a pointer
Subtracting one pointer from another
Comparing two pointers
Adding an integer to, or subtracting an integer from, a pointer
Each time a pointer is incremented, it points to the memory location of the next element
of its base type.
Each time it is decremented, it points to the location of the previous element.
When applied to char pointers, this will appear as ''normal" arithmetic because a char
object is always 1 byte long
All other pointers will increase or decrease by the length of the data type they point to.
Example:
Let p1 be an integer pointer with a current value of 2000.
After the expression p1++ or p=p+1
p1 contains 2002, not 2001.
The reason for this is that each time p1 is incremented; it will point to the next integer.
main()
{
int a=10;
int *p;
p=&a;
clrscr();
printf("p=%u",p); /* if p=2000*/
p++;
printf("p=%u",p); /*p=2002*/
p=p+2;
printf("p=%u",p);/*p=2006 */
getch();
}
Pointer arithmetic on arrays
main()
{
DVNR/IT/C/Pointers Page 2
int a[] = {10,20,30,40,50};
int *p = a; /*The pointer points tothe start of the array*/
printf(''%d \n", *p);
p++; // 2 is actually added
printf("%d \n", *p);
p++; // 2 is actually added
printf("%d \n", *p);
p++; // 2 is actually added
printf("%d \n", *p);
p++; // 2 is actually added
printf("%d \n\n", *p);
}
o/p: 10,20,30,40,50
Subtracting an integer from, a pointer
The same is true of decrements. For example, assuming that p1 has the value 2000, the
expression p1- - or p=p-1; causes p1 to have the value 1998.
main()
{
int a=10,b=20;
int *p,*q;
p=&a; q=&b;
clrscr();
printf("p=%u",p); /* if p=2000*/
printf("p=%u",q); / if p=2002*/
printf(“q-p=%d”,q-p); /*q-p=1 */
getch();
}
Pointer Comparisons
The comparison p1 < p2 yields TRUE if the element referenced by p2 has a greater index than
the element referenced by p1. Otherwise, the comparison yields FALSE.
main()
{
int a=10,b=20;
int *p,*q;
p=&a;
DVNR/IT/C/Pointers Page 3
q=&b;
clrscr();
printf("p=%u",p); if p=2000
printf("p=%u",q); if q=2002
if(p>q)
printf("true");
else
printf("false");
getch();
}
o/p: if p=2000(address of p) and if q=2002(address of q)---false will be printed
Operations that can’t be applied on pointers
We cannot multiply or divide pointers
We cannot add two pointers;
We cannot apply the bitwise operators to them;
We cannot add or subtract type float or double to or from pointers.
Pointer to Pointer
A pointer to a pointer is a form of multiple indirection, or a chain of pointers. Normally, a
pointer contains the address of a variable. When we define a pointer to a pointer, the first
pointer contains the address of the second pointer, which points to the location that
contains the actual value.
int main () {
int var;
int *ptr;
int **pptr;
var = 10;
/* take the address of var */
ptr = &var;
/* take the address of ptr using address of operator & */
pptr = &ptr;
DVNR/IT/C/Pointers Page 4
/* take the value using pptr */
printf("Value of var = %d\n", var ); /* 10 gets printed */
printf("Value available at *ptr = %d\n", *ptr ); /* 10 gets printed */
printf("Value available at **pptr = %d\n", **pptr); /* 10 gets printed */
return 0;
}
DVNR/IT/C/Pointers Page 5
Dynamic Memory Management
Memory management in C can be done in two different ways
Static memory allocation
Dynamic memory allocation
Static memory allocation
If the amount of memory required for the program is known in advance then we can use static memory
allocation.
Eg: int a[100];
In the above statement an amount of 200 bytes of memory will be allocated for the array a. In static
memory allocation there is no way to increase or decrease the array size during the execution of the
program.
Disadvantage
Memory wastage
During the run time if we store only 50 data elements in the array, the rest of the memory will be
wasted.
Insufficient Memory
During the run time if we want to store more than 100 elements in the given array, memory may not be
sufficient.
Dynamic memory allocation
If we want to allocate memory only at the time of execution of the program, we can use
dynamic memory allocation.
Some times the amount of memory required for the program may not be known until run time.
In this situation we can go for dynamic memory allocation.
Memory will be allocated from Heap.
DVNR/IT/C/Pointers Page 6
Functions used in Dynamic memory management
malloc()
calloc()
realloc()
free()
malloc()
The simplest standard library function that allocates memory at runtime is called malloc().
When we use the malloc() function, we have to specify the number of bytes of memory that we
want as an argument.
This function returns the address of the first byte of memory allocated
If there is not enough available memory to satisfy the malloc( ) request, an allocation failure
occurs and malloc( ) returns a null.
By default the memory allocated by malloc() contains garbage values
void *malloc( size_t size );
int *p;
p = malloc(50*sizeof(int)); allocates space for 50 integers
#include<stdlib.h>
main()
{
Int *p,i,n;
Printf(“How many numbers u want to store”)
Scanf(“%d”,&n);
p = (int *)malloc(n*sizeof(int));
if(p==NULL)
{
printf(''Out of memory.\n");
exit (1);
}
for(i=0;i<n;i++)
scanf(“%d”,(p+i));
printf(”elements u have entered are”);
for(i=0;i<n;i++)
printf(“%d”,*(p+i));
free(fp);
}
calloc()
It allocates memory as an array of elements of a given size
It initializes the memory that is allocated so that all bits are zero
The calloc() function requires you to supply two argument values
o The number of elements in the array
o The size of the array element
DVNR/IT/C/Pointers Page 7
void *calloc( size_t count, size_t size );
#include<stdlib.h>
main()
{
Int *p,i,n;
Printf(“How many numbers u want to store”)
Scanf(“%d”,&n);
p = (int *)calloc(n,sizeof(int));
if(p==NULL)
{
printf(''Out of memory.\n");
exit (1);
}
for(i=0;i<n;i++)
scanf(“%d”,(p+i));
printf(”elements u have entered are”);
for(i=0;i<n;i++)
printf(“%d”,*(p+i));
free(fp);
}
realloc()
void *realloc( void * ptr, size_t size );
The realloc( ) function releases the memory block addressed by ptr and allocates a new
block of size bytes, returning its address.
The new block may start at the same address as the old one.
realloc( ) also preserves the contents of the original memory block up to the size of
whichever block is smaller.
If the new block doesn't begin where the original one did, then realloc( ) copies the
contents to the new memory block.
If the new memory block is larger than the original, then the values of the additional
bytes are unspecified.
Releasing Dynamically Allocated Memory
free()
When we allocate memory dynamically, we should always release the memory when it
is no longer required.
To release the memory for a block of dynamically allocated memory we use free( )
void free(void *p);
where p is a pointer to memory that was previously allocated
DVNR/IT/C/Pointers Page 8