Sunday, July 3, 2011

Various types of C pointers


Generic pointer:

void pointer in c is known as generic pointer. A generic pointer is a pointer which can point type of data.

Example:

void *gptr;
Here gptr is generic pointer.

Important points about generic pointer in c.

1. We cannot dereference generic pointer.

#include "malloc.h"
void main(){
void *gptr;
printf("%d",*gptr);

}

Output: Compiler error

2. We can find the size of generic pointer using sizeof operator.

#include "string.h"
void main(){
void *gptr;
printf("%d",sizeof(gptr));

}

Output: 2
Explanation: Size of any type of near pointer in c is two byte.

3. Generic pointer can hold any type of pointers like char pointer, struct pointer, array of pointer etc without any typecasting.

Example:
void main(){
char c='A';
int i=4;
void *gp;
char *gq=&c;
int *gr=&i;
p=q;
printf("%c",*(char *)p);
p=r;
printf("%d",*(int *)p);

}
Output: A4

4. Any type of pointer can hold generic pointer without any typecasting.

5. Generic pointers are used when we want to return such pointer which is applicable to all types of pointers. For example return type of malloc function is generic pointer because it can dynamically allocate the memory space to stores integer, float, structure etc. hence we type cast its return type to appropriate pointer type.

Examples:

1.

char *gc;
gc=(char *)malloc(sizeof(char));

2.

double *gd;
gd=(double *)malloc(sizeof(double));

3.
Struct student{
char *gname;
int roll;
};
Struct student *gstu;
gstu=(struct student *)malloc(sizeof(struct student));

--------------------

NULL pointer:

Literal meaning of NULL pointer is a pointer which is pointing to nothing. NULL pointer points the base address of segment.
Examples of NULL pointer:
1. int *ptr=(char *)0;
2. float *ptr=(float *)0;
3. char *ptr=(char *)0;
4. double *ptr=(double *)0;
5. char *ptr=’\0’;
6. int *ptr=NULL;
(q) What is meaning of NULL?
Answer:
NULL is macro constant which has been defined in the heard file stdio.h, alloc.h, mem.h, stddef.h and stdlib.h as
#define NULL 0
Examples:
(1)What will be output of following c program?
#include "stdio.h"
void main(){
if(!NULL)
printf("I know preprocessor");
else
printf("I don't know preprocessor");
}
Output: I know preprocessor
Explanation:
!NULL = !0 = 1
In if condition any non zero number mean true.
(2)What will be output of following c program?
#include "stdio.h"
void main(){
int i;
static int count;
for(I = NULL; I <= 5; ){
count++;
i+=2;
}
printf("%d\n",count);
}
Output: 3
(3)What will be output of following c program?
#include "stdio.h"
void main(){
#ifndef NULL
#define NULL 5
#endif
printf("%d\n", NULL + sizeof(NULL));
}
Output: 2
Explanation:
NULL + sizeof(NULL)
=0+sizeoof(0)
=0+2 //size of int data type is two byte.
We cannot copy anything in the NULL pointer.
Example:
(q)What will be output of following c program?
#include "string.h"
void main(){
char *str = NULL;
strcpy(str,"saurabhgupta0527.blogspot.com");
printf("%s\n",str);
}
Output: (null)
--------------------

Wild pointer:

A pointer in c which has not been initialized is known as wild pointer.

Example:

(q)What will be output of following c program?

void main(){
int *wptr;
printf("%u\n",wptr);
printf("%d\n",*wptr);
}

Output: Any address
Garbage value


Here wptr is wild pointer because it has not been initialized.
There is difference between the NULL pointer and wild pointer. Null pointer points the base address of segment while wild pointer doesn’t point any specific memory location.

---------------------------------------------

Dangling pointer:

If any pointer is pointing the memory address of any variable but after some variable has deleted from that memory location while pointer is still pointing such memory location. Such pointer is known as dangling pointer and this problem is known as dangling pointer problem.
Initially:

     ptr                                                               a
   7000             -------------------à                     25
   8000                                                           7000
Later:
     ptr                                                                 a       
   7000             -------------------à                     <N/A>
   8000                                                            <N/A>
For example:
(q)What will be output of following c program?
int *call();
void main(){
int *dptr;
dptr = call();
clrscr();
printf("%d\n",*dptr);
}
int * call(){
int x=25;
++x;
return &x;
}
Output: Garbage value
Explanation: variable x is local variable. Its scope and lifetime is within the function call hence after returning address of x variable x became dead and pointer is still pointing ptr is still pointing to that location.
Solution of this problem: Make the variable x is as static variable.
In other word we can say a pointer whose pointing object has been deleted is called dangling pointer.
----------------------------------

Near pointer:

The pointer which can points only 64KB data segment or segment number 8 is known as near pointer.


That is near pointer cannot access beyond the data segment like graphics video memory, text video memory etc. Size of near pointer is two byte. With help keyword near, we can make any pointer as near pointer.
Examples:
(1)
void main(){
int x=25;
int near* ptr;
ptr=&x;
printf(“%d\n”,sizeof ptr);
}
Output: 2
(2)
void main(){
int near* near * ptr;
printf(“%d\n”,sizeof(ptr),sizeof(*ptr));
}
Output: 2 2
Explanation: Size of any type of near pointer is two byte.
Near pointer only hold 16 bit offset address. Offset address varies from 0000 to FFFF (in hexadecimal).
Note: In printf statement to print the offset address in hexadecimal, %p is used.
Example:
void main(){
int i=10;
int *ptr=&i;
printf("%p",ptr);
}
Output: Offset address in hexadecimal number format.
%p is also used to print any number in hexadecimal number format.
Example:
void main(){
int a=12;
printf("%p",a);
}
Output: 000C
Explanation: Hexadecimal value of 12 is C.
Consider the following two c program and analyze its output:
(1)
void main(){
int near * ptr=( int *)0XFFFF;
ptr++;
ptr++;
printf(“%p”,ptr);
}
Output: 0003
(2)
void main(){
int i;
char near *ptr=(char *)0xFFFA;
for(i=0;i<=10;i++){
printf("%p\n", ptr);
ptr++;
}
}
Output:
FFFA
FFFB
FFFC
FFFD
FFFE
FFFF
0000
0001
0002
0003
0004
Explanation: When we increment or decrement the offset address from maximum and minimum value respectively then it repeats the same value in cyclic order. This property is known as cyclic nature of offset address.
----------------------

Far pointer:

The pointer which can point or access whole the residence memory of RAM i.e. which can access all 16 segments is known as far pointer.


Size of far pointer is 4 byte or 32 bit.
Examples:
(1) What will be output of following c program?
void main(){
int x=10;
int far *fptr;
fptr=&x;
printf("%d\n",sizeof(fptr));
}
Output: 4
What is segment number and offset address?
Example:
void main(){
int x = 100;
int far *fptr;
fptr = &x;
printf("%Fp\n",fptr);
}
Output: 8FD8:FFF4
Here 8FD8 is segment address and FFF4 is offset address in hexadecimal number format.
Note: %Fp is used for print offset and segment address of pointer in printf function in hexadecimal number format.
In the header file dos.h there are three macro functions to get the offset address and segment address from far pointer and vice versa.
1. FP_OFF(): To get offset address from far address.
2. FP_SEG(): To get segment address from far address.
3. MK_FP(): To make far address from segment and offset address.
Limitation of far pointer:
We cannot change or modify the segment address of given far address by applying any arithmetic operation on it. That is by using arithmetic operator we cannot jump from one segment to other segment. If you will increment the far address beyond the maximum value of its offset address instead of incrementing segment address it will repeat its offset address in cyclic order.
Example:
(q)What will be output of following c program?
void main(){
int i;
char far *fptr = (char *)0xB800FFFA;
for(I = 0; I <= 10; i++){
printf("%Fp\n", fptr);
fptr++;
}
}
Output:
B800:FFFA
B800:FFFB
B800:FFFC
B800:FFFD
B800:FFFE
B800:FFFF
B800:0000
B800:0001
B800:0002
B800:0003
B800:0004
This property of far pointer is called cyclic nature of far pointer within same segment.
Important points about far pointer:
1. Far pointer compares both offset address and segment address with relational operators.
Examples:
(1)What will be output of following c program?
void main(){
int far *fp=(int *)0X70230000;
int far *fq=(int *)0XB0210000;
if(fp==fq)
printf("pointers are equal\n");
else
printf("pointers are not equal\n");
}
Output: Both pointers are not equal
(2)What will be output of following c program?
void main(){
int far *fp=(int *)0X70230000;
int far *fq=(int *)0XB0210000;
int near *nx, near *ny;
nx=(int near *)np;
ny=(int near *)nq;
if(nx == ny)
printf("Both pointer are equal\n");
else
printf("Both pointer are not equal\n");
}
Output: Both pointers are equal
2. Far pointer doesn’t normalize.
What is normalization of pointer?
------------------------------------

Huge pointer:

The pointer which can point or access whole the residence memory of RAM i.e. which can access all the 16 segments is known as huge pointer.



Size of huge pointer is 4 byte or 32 bit.

Normalization of huge pointer:

Turbo C compiler is based on 8085 microprocessor in which physical address of memory is represented in 20 bit. Conversion of 4 byte or 32 bit huge address into 20 bit actual physical address is known as normalization.

Formula to calculate physical address:



Example:

(q) What will be physical address of huge address 0X59994444?

Answer:
Huge address: 0X59994444
Offset address: 0x4444
Segment address: 0x5999

Physical address= Segment address * 0X10 + Offset address
=0X5999 * 0X10 +0X4444
=0X59990 + 0X4444
=0X5DDD4
In binary: 0101 1101 1101 1101 0100

Note: Each hexadecimal digit is represented in 4 bit binary number.

When any relation operation is performed between two huge pointers first it normalizes in actual physical address.

Example:

(q)What will be output of following c program?

void main(){
int huge*hp=(int huge*)0XC0563331;
int huge*hq=(int huge*)0xC2551341;
clrscr();
if(hp == hq) {
printf("Equal");
}
else {
printf("Not equal");
}
}

Output: Equal
Explanation:

As we know huge pointers compare its physical address.
Physical address of huge pointer p

Huge address: 0XC0563331
Offset address: 0x3331
Segment address: 0XC056

Physical address= Segment address * 0X10 + Offset address
=0XC056 * 0X10 +0X3331
=0XC0560 + 0X3331
=0XC3891

Physical address of huge pointer q

Huge address: 0XC2551341
Offset address: 0x1341
Segment address: 0XC255

Physical address= Segment address * 0X10 + Offset address
=0XC255 * 0X10 +0X1341
=0XC2550 + 0X1341
=0XC3891

Since both huge pointers p and q are pointing same physical address so if condition will true.



(q)What will be output of following c program?


void main(){
double near *np, far *fq;
printf("%d %d %d",sizeof(nq),sizeof(np),sizeof(*np));

}

Output: 4 2 8
Explanation: q is far pointer, p is near pointer, *p is double data type constant.

Don’t use huge pointer:

If you will increment huge pointer it will increment both offset and segment address unlike to far pointer which only increments offset address. So if you have little knowledge about huge pointer and you are using huge pointer then you can easily access and modify the IVT, device driver memory, video memory etc. This might be dangerous for your computer.

(q)Why there are three types of pointer in Turbo c compiler?

Answer:
Turbo c compiler is based on Dos operating system which is based on 8085 microprocessors. In 8085 microprocessor actual physical address is represented in 20 bit. But there are not any pointers which can point 20 bit address. Considering simplicity of calculations, access to actual physical address, security etc. c has introduced three type of pointer i.e. near, far and huge pointer.

No comments:

Post a Comment