So far, we’ve learned that the address associated with a pointer must be of the same type as the pointer declaration. If we define an “int” pointer, for example, it cannot point to a float variable or any other type of variable; instead, it can only point to “int” type variables.
We utilize a pointer to void to solve this problem. A pointer to void is a universal pointer that can be used to point to any data type. A void pointer can be assigned to any type of pointer, and a void pointer can be assigned to any type of pointer without any explicit typecasting.
Syntax Of void pointer:
void *pointer_name;
The Declaration of the void pointer is given below:
void *ptr;
The type of the pointer is void, and the name of the pointer is ‘ptr’ in the above declaration:
Let us consider some examples:
Size of the void pointer in C/C++:
In C/C++, the void pointer has the same size as a character type pointer. A pointer to void has the same representation in C/C++ as a pointer to a character type. Depending on the platform you’re using, the size of the pointer will differ.
Let’s look at the below example:
#include <stdio.h> int main() { void *ptr = NULL; //void pointer int *p = NULL;// integer pointer char *cp = NULL;//character pointer float *fp = NULL;//float pointer //size of void pointer printf("size of void pointer = %d\n\n",sizeof(ptr)); //size of integer pointer printf("size of integer pointer = %d\n\n",sizeof(p)); //size of character pointer printf("size of character pointer = %d\n\n",sizeof(cp)); //size of float pointer printf("size of float pointer = %d\n\n",sizeof(fp)); return 0; }
Output:
size of void pointer = 8
size of integer pointer = 8
size of character pointer = 8
size of float pointer = 8
Advantages Of void Pointer:
The main advantage of void Pointer is –
The void pointer is returned by the malloc() and calloc() procedures, so they can be used to allocate memory of any type.
#include <stdio.h> #include<malloc.h> int main() { int a=90; int *x = (int*)malloc(sizeof(int)) ; x=&a; printf("Value which is pointed by x pointer : %d",*x); return 0; }
Output:
The value which is pointed by x pointer: 90
- The generic functions in C/C++ can also be implemented using the void pointer.
The following are some key points about the void pointer:
Dereferencing a void pointer in C:
In C, the void pointer cannot be directly dereferenced. Take a look at the sample below.
#include <stdio.h> int main() { int a=90; void *ptr; ptr=&a; printf("Value which is pointed by ptr pointer : %d",*ptr); return 0; }
*ptr is a void pointer that points to the integer variable ‘a’ in the above code. Because the void pointer cannot be dereferenced, the above code will generate a compile-time error because the value of the variable referred to by the pointer ‘ptr’ is printed directly.
Output:
Compilation failed due to following error(s).
main.c In function 'main':
main.c:17:56: warning: dereferencing 'void *' pointer
printf("Value which is pointed by ptr pointer : %d", *ptr);
main.c:17:4: error: invalid use of void expression
printf("Value which is pointed by ptr pointer : %d", *ptr);
Now, we rewrite the above code to remove the error.
#include <stdio.h> int main() { int a=90; void *ptr; ptr=&a; printf("Value which is pointed by ptr pointer : %d",*(int*)ptr); return 0; }
Output:
Value which is pointed by ptr pointer : 90
We typecast the void pointer to an integer pointer in the previous function by using the following statement:
(int*)ptr;
Then, using the statement below, we output the value of the variable pointed by the void pointer ‘ptr’:
*(int*)ptr;
Arithmetic operation on void pointers:
In C/C++, we can’t directly apply arithmetic operations on void pointers. So that we can execute arithmetic operations on void pointers, we must use the right typecasting.
Let’s see the below example:
#include<stdio.h> int main() { float a[4]={6.1,2.3,7.8,9.0}; void *ptr; ptr=a; for(int i=0;i<4;i++) { printf("%f,",*ptr); ptr=ptr+1; // Incorrect. } }
The above code displays the compile-time error “illegal usage of void expression” because we cannot perform arithmetic operations directly on a void pointer, i.e., ptr=ptr+1.
Let’s rewrite the above code to remove the error:
#include<stdio.h> int main() { float a[4]={6.1,2.3,7.8,9.0}; void *ptr; ptr=a; for(int i=0;i<4;i++) { printf("%f,",*((float*)ptr+i)); } }
Because we applied the necessary casting on the void pointer, i.e., (float*)ptr, and then we applied the arithmetic operation, i.e., *((float*)ptr+i), the above code works successfully.
Output:
6.100000,2.300000,7.800000,9.000000
Why do we use void pointers?
We use void pointers because they can be reused. We can store any type of object in void pointers, and we can get any type of object by using the indirection operator with suitable typecasting.
Let’s understand through an example.
#include<stdio.h> int main() { int a=56; // initialization of a integer variable 'a'. float b=4.5; // initialization of a float variable 'b'. char c='k'; // initialization of a char variable 'c'. void *ptr; // declaration of void pointer. // assigning the address of variable 'a'. ptr=&a; printf("value of 'a' is : %d",*((int*)ptr)); // assigning the address of variable 'b'. ptr=&b; printf("\nvalue of 'b' is : %f",*((float*)ptr)); // assigning the address of variable 'c'. ptr=&c; printf("\nvalue of 'c' is : %c",*((char*)ptr)); return 0; }
Output:
value of 'a' is : 56
value of 'b' is : 4.500000
value of 'c' is : k
Difference between void pointers in C and C++:
We can assign the void pointer to any other pointer type without typecasting in C/C++, but we must typecast in C++ when we assign the void pointer to any other pointer type.
Let’s understand through a simple example.
In C:
#include <stdio.h> int main() { void *ptr; // void pointer declaration int *ptr1; // integer pointer declaration int a =90; // integer variable initialization ptr=&a; // storing the address of 'a' in ptr ptr1=ptr; // assigning void pointer to integer pointer type. printf("The value of *ptr1 : %d",*ptr1); return 0; }
We define two pointers, ‘ptr’ and ‘ptr1’, of type void and integer, respectively, in the above program. The integer type variable, ‘a,’ is also declared. We assign the address of the ‘a’ variable to the pointer ‘ptr’ after declaring it.
Then, without typecasting, we assign the void pointer to the integer pointer, ptr1, because in C/C++, we don’t need to typecast when assigning a void pointer to any other type of pointer.
Output:
The value of *ptr1 : 90
In C++:
#include <iostream> using namespace std; int main() { void *ptr; // void pointer declaration int *ptr1; // integer pointer declaration int data=10; // integer variable initialization ptr=&data; // storing the address of data variable in void pointer variable ptr1=(int *)ptr; // assigning void pointer to integer pointer std::cout << "The value of *ptr1 is : " <<*ptr1<< std::endl; return 0; }
We declare two pointer variables of type void and int, respectively, in the above program. We also make a new integer type variable called ‘data.’ We store the address of variable ‘data’ in a void pointer variable, ptr, after declaring it.
Now we want to convert the void pointer to an integer pointer. To do so, we must use the cast operator on the void pointer variable, i.e. (int *). This cast operator informs the compiler about the type of value held by the void pointer. To cast, type the data type followed by a * in a bracket, such as (char *) or (int *).
Output:
The value of *ptr1 is : 10
If you want to improve then connect us.