top

Search

Software Key Tutorial

.

UpGrad

Software Key Tutorial

Void Pointer

Introduction 

A void pointer is a generic pointer that can carry the address of any data type without defining its specific type, in contrast to other pointer types. Because of their adaptability, void pointers are beneficial in scenarios where the data type is unknown or subject to change over time.

However, you cannot directly dereference or use pointer arithmetic on a void pointer since it lacks information about the type it points to. You must first cast a void pointer to the proper data type to retrieve the data it points to.

In this article, let's learn in detail about what is a void pointer in C,  what is a generic pointer in C, a generic pointer in C example, and many more! 

Overview 

In situations when the data type is unknown beforehand or may change dynamically while the application is running, void pointers are most commonly used. They are frequently used in low-level programming, as well as in the creation of generic data structures and multi-data type functions. However, since they do not provide type safety, utilizing void pointers calls for caution. To prevent memory access issues and undefined behavior, it is imperative to ensure proper casting while working with void pointers.

You normally get a memory address to utilize a void pointer by getting the address of a variable or by using dynamic memory allocation routines like malloc(). You must cast the void pointer to the proper data type before dereferencing it if you need to access the data it points to. Incorrect memory access can cause incorrect casting, which can cause program crashes or data corruption.

Void pointers offer a flexible way to interact generically and dynamically with various data types. To enable secure and dependable code execution, their use necessitates a thorough understanding of memory management and appropriate casting.

What is Void Pointer in C++?  

A void pointer in C++ can point to an object of any data type and is denoted by the symbol void*. A void pointer in C++ does not have a corresponding data type. It can therefore store any type of object's memory location, but it is unaware of the amount or structure of the data it links to.

As they are generic, void pointers are frequently employed when dealing with functions or data structures that need to handle a variety of data types or when the precise data type is unknown. For instance, void pointers are used in some libraries or APIs that require working with data of many types as a way to send data around without being constrained to a particular type.

There is a restriction when utilizing void pointers, though. You cannot directly dereference or use pointer arithmetic on the void pointer since the compiler is unaware of the sort of data it is pointing to. You must first cast the void pointer to the right data type to retrieve the data it points to. For proper memory access and accurate data interpretation, this casting is necessary.

Syntax of Void Pointer

In C programming, a void pointer (also known as a "generic pointer") is a special pointer type that can hold the address of any data type, including functions. It is used when you want to create a pointer without specifying its data type upfront. However, because the data type is not known at compile time, you need to cast the void pointer to the appropriate type before dereferencing it. 

The syntax of a void pointer in C is as follows:

void *ptr;

Here, ptr is a void pointer that can hold the address of any data type. To use this pointer, you typically need to cast it to the correct data type before performing any operations on it.

For example:

int num = 42;
float value = 3.14;
void *ptr;

ptr = #
printf("Value at ptr: %d\n", *((int *)ptr));

ptr = &value;
printf("Value at ptr: %f\n", *((float *)ptr));

In this example, the void pointer ptr is first assigned the address of an integer (num), and then the address of a float (value). Before dereferencing the void pointer, it is cast to the appropriate data type (int or float).

Code:

#include <stdio.h>
int main()
{
int p = 12;
void* pt = &p;
printf("%d", *(int*)pt);
return 0;
}

Size of Void Pointer in C:

In most C implementations, the size of a void pointer (void *) is the same as the size of a regular pointer to an object of any data type. This size depends on the architecture and compiler you're using.

Commonly:

  • On 32-bit systems, the size of a void pointer is typically 4 bytes.

  • On 64-bit systems, the size of a void pointer is typically 8 bytes.

However, the actual size can vary depending on the specific system and compiler settings. To determine the size of a void pointer on your system, you can use the sizeof operator:

Code:

#include <stdio.h>

int main() {
    printf("Size of void pointer: %zu bytes\n", sizeof(void *));
    return 0;
}

Advantages of Void Pointer:

 Void pointers (void *) in C offer several advantages in certain programming scenarios:

  • Generic Pointer: Void pointers provide a way to create generic interfaces or functions that can operate on different data types without having to write separate code for each type. This is particularly useful in data structures and algorithms that need to work with various types of data.

  • Dynamic Type Casting: Void pointers allow you to perform typecasting dynamically based on the situation. This flexibility is valuable when you have to work with unknown or varying data types at runtime.

  • Memory Allocation: When using functions like malloc or calloc to allocate memory, the return value is a void pointer. This enables you to allocate memory for any type of data and then cast the pointer to the appropriate type.

  • Callback Functions: Void pointers are often used in callback functions, where you pass a function pointer along with a context (void pointer). The callback function can then be called with the context to provide additional information.

  • Opaque Data Structures: Void pointers are used to create opaque data structures, which hide the internal implementation details of a structure from the user. This helps in creating more modular and maintainable code.

  • Interfacing with External Libraries: Many external libraries and APIs use void pointers to allow you to pass custom data or structures to their functions, enabling integration with the library regardless of the specific data type.

  • Polymorphism: In C, polymorphism can be achieved to some extent using void pointers. You can create functions that accept void pointers to different types and implement different behaviour based on the actual type.

  • Minimising Code Duplication: Void pointers can help reduce code duplication by allowing you to write generic utility functions that work with various types of data.

Code:

#include <stdio.h>  
#include<malloc.h>  
int main()  
{  
   int k=80;  
   
   int *p = (int*)malloc(sizeof(int)) ;  
   p=&k;  
   printf("Value which is pointed by p pointer : %d",*p);  
    return 0;  
}  

Important Points Related to Void Pointer

Dereferencing a Void Pointer in C

We cannot dereference the void pointer in C directly. See the example,

Code:

#include <stdio.h>  
int main()  
{  
   int x=90;  
   void *ptr;  
   ptr=&x;  
   printf("Value which is pointed by ptr pointer : %d",*ptr);  
   return 0;  
}  

In this code, *ptr is a void pointer that points to the integer variable 'x'. We know that void pointers can’t be dereferenced, so in this code will give the compile-time error because we are printing the value of the variable pointed by the pointer 'ptr' directly.

In this above code, we typecast the void pointer to the integer pointer by using the statement given below:

(int*)ptr;

After that, we are able to print the values of the variables that are pointed by the void pointers 'ptr' by using the statement given below:

*(int*)ptr;

Now, we are rewriting the above code to remove the error:

Code:

#include <stdio.h>  
int main()  
{  
   int x=80;  
   void *ptr;  
   ptr=&x;  
   printf("Value which is pointed by ptr pointer : %d",*(int*)ptr);  
    return 0;  
}  

Arithmetic Operations on Void Pointer

In C We cannot apply the arithmetic operations on void pointers. We have to apply the proper typecasting to perform the arithmetic operations on the void pointers.

See the example:

Code:

int main()   
{   
   float p[4]={6.1,2.3,7.8,9.0};  
   void *ptr;  
   ptr=p;  
   for(int i=0;i<4;i++)  
  {  
      printf("%f,",*ptr);  
      ptr=ptr+1;         // Incorrect.  
     
}}  

This program above shows the error "invalid use of void expression" during compilation as we are not able to apply arithmetic operations on void pointers directly, i.e., ptr=ptr+1.

Now, we are rewriting the above code to remove the error:

Code:

#include<stdio.h>   
int main()   
{   
   float p[4]={6.1,2.3,7.8,9.0};  
   void *ptr;  
   ptr=p;  
   for(int i=0;i<4;i++)  
  {  
      printf("%f,",*((float*)ptr+i));  
   }}  

Why Do We Use Void Pointers? 

Void pointers are used for several reasons in C and C++ programming. They: 

Generic Programming: Using void pointers, a single function or data structure can be used to operate with several data types in generic programming. This is especially helpful if you want to write reusable code that can handle different data types without having to write separate pieces of code for each kind.

Dynamic Memory Allocation: With dynamic memory allocation functions like malloc() or calloc() in C and new operators in C++, void pointers are frequently employed. The correct data type must be returned to its previous forms before accessing any allocated memory. 

Function Pointers: Function pointers can be converted to and from void pointers in C and C++. You use this capability to store them in data structures is one of the biggest use of void pointers in C. You can store numerous function pointers with varied signatures in a single data structure by casting to a void pointer.

Interfacing with External Libraries: You must utilize void pointers to send or receive data when interacting with external libraries or APIs that use them to pass data. You can accurately extract or analyze the data by casting to the proper data type.

Memory Manipulation: Void pointers are sometimes used for low-level memory manipulation or type punning. However, using void pointers for these purposes requires careful consideration and adherence to strict-aliasing rules to avoid undefined behavior.

Despite their adaptability, void pointers come with significant hazards. Improper casting or dereferencing can result in memory problems, crashes, or data corruption because the type of information is not retained. It is crucial to handle void pointers carefully, provide proper type management, and maintain memory safety.

Conclusion 

Overall, a void pointer is a useful tool for C programmers, but using it effectively needs a solid grasp of memory management, type casting, and adherence to best practices. Void pointers can considerably increase the adaptability and versatility of C programs when utilized wisely and carefully.

In conclusion, void pointers (void*) are essential in C programming because they provide a strong and adaptable framework for handling data of varied or ambiguous kinds. When generic programming is required, void pointers are crucial because they may hold any data type in a single pointer. They make it possible to develop generic algorithms and data structures that can be applied to various data types, encouraging the modularity and maintainability of the code.

FAQs 

  1. What cannot be done on the void pointer? 

In C or C++, you cannot directly dereference or execute pointer arithmetic on a void pointer ('void*'). Additionally, until you explicitly convert the data to the correct data type, you cannot access the data it points to. To access the underlying data safely, void pointers must first be cast to the correct type because they lack type information.

  1. Can you delete a void pointer? 

The delete operator in C++ or the free() function in C cannot calculate the proper deallocation size for a void pointer because it lacks type information. You must first convert memory allocated via a void pointer to the relevant data type before using the proper deallocation function (such as delete for C++ objects or free() for dynamically allocated memory) to properly release the memory.

  1. What is the size of a void pointer in C? 

The size of a void pointer ('void*') in C depends on the platform. It normally has the same size as a system regular pointer, which on a 32-bit system is typically 4 bytes and on a 64-bit system is often 8 bytes. The void pointer can point to any sort of object because it is made to contain memory addresses rather than being tied to any particular data type.

Leave a Reply

Your email address will not be published. Required fields are marked *