Ad Code

Responsive Advertisement

void pointer in C ? With example | Advantages of void pointer | Why we use void pointers?

 void pointer in C

Till now, we have studied that the address assigned to a pointer should be of the same type as specified in the pointer declaration.

A void pointer in C is a special type of pointer that doesn't have a specific data type associated with it. It is also known as a "generic pointer." This means that a void pointer can point to an object of any data type. It is often used for scenarios where you want to create more flexible and generic code that can work with various data types.

syntax:

c
void *pointer_name;

Here's a breakdown of the syntax elements:

1.void: This keyword indicates that the pointer is of type void, which means it doesn't have a specific data type associated with it.

2.*: The asterisk * is used to declare a pointer. It tells the C compiler that pointer_name is a pointer variable.


3. pointer_name: You can choose any valid C identifier as the name for your void pointer. This is the name you'll use to reference the pointer variable in your code.


Declaration of the void pointer is given below:

c
void *ptr;


Let us consider some examples:

int i=9; // integer variable initialization.

int *p; // integer pointer declaration.

float *fp; // floating pointer declaration.

void *ptr; // void pointer declaration.

p=fp; // incorrect.

fp=&i; // incorrect

ptr=p; // correct

ptr=fp; // correct

ptr=&i; // correct


Size of the void pointer in C

The size of a void pointer in C is determined by the system's architecture and compiler. It's typically the same as the size of a regular data pointer on that system. On a 32-bit system, it's usually 4 bytes, and on a 64-bit system, it's typically 8 bytes.

Here's an example that demonstrates the size of a void pointer on a 64-bit system and prints the size:

c
#include <stdio.h> int main() { void *ptr = NULL; // Declare a void pointer and initialize it to NULL // Print the size of the void pointer in bytes printf("Size of void pointer: %zu bytes\n", sizeof(ptr)); return 0; }


When you run this code on a 64-bit system, you will typically get output like this:

arduino
Size of void pointer: 8 bytes

This output indicates that on a 64-bit system, the size of a void pointer is 8 bytes. On a 32-bit system, you would typically see "4 bytes" as the output. Keep in mind that this value may vary depending on the specific system and compiler you are using.


Advantages of void pointer

1. Generic Programming:

c
#include <stdio.h> void printValue(void *ptr, char type) { if (type == 'i') { int *intPtr = (int *)ptr; printf("Value: %d\n", *intPtr); } else if (type == 'd') { double *doublePtr = (double *)ptr; printf("Value: %lf\n", *doublePtr); } } int main() { int intValue = 42; double doubleValue = 3.14159; printValue(&intValue, 'i'); // Prints: Value: 42 printValue(&doubleValue, 'd'); // Prints: Value: 3.141590 return 0; }


In this example, we use a void pointer to create a generic printValue function that can print the value of an integer or double based on the specified type.


2 .Flexibility:


c
#include <stdio.h> void print(void *data, int dataType) { if (dataType == 0) { int *intPtr = (int *)data; printf("Integer: %d\n", *intPtr); } else { double *doublePtr = (double *)data; printf("Double: %lf\n", *doublePtr); } } int main() { int intValue = 42; double doubleValue = 3.14159; print(&intValue, 0); // Prints: Integer: 42 print(&doubleValue, 1); // Prints: Double: 3.141590 return 0; }


Here, we demonstrate flexibility by allowing the print function to work with different data types based on the dataType argument.


3. Memory Allocation:

c
#include <stdio.h> #include <stdlib.h> int main() { void *ptr; int *intPtr; ptr = malloc(sizeof(int)); // Allocate memory for an int if (ptr == NULL) { printf("Memory allocation failed.\n"); return 1; } intPtr = (int *)ptr; // Cast void pointer to int pointer *intPtr = 42; // Assign a value printf("Value: %d\n", *intPtr); free(ptr); // Release the allocated memory return 0; }



This example shows how a void pointer is used in dynamic memory allocation with malloc, and then it's cast to an int pointer for data storage.


4. Heterogeneous Data Structures:

c
#include <stdio.h> struct GenericItem { void *data; int type; // 0 for int, 1 for double }; int main() { struct GenericItem item1, item2; int intValue = 42; double doubleValue = 3.14159; item1.data = &intValue; item1.type = 0; item2.data = &doubleValue; item2.type = 1; printf("Item 1: "); if (item1.type == 0) { int *intPtr = (int *)item1.data; printf("Value: %d\n", *intPtr); } else { double *doublePtr = (double *)item1.data; printf("Value: %lf\n", *doublePtr); } printf("Item 2: "); if (item2.type == 0) { int *intPtr = (int *)item2.data; printf("Value: %d\n", *intPtr); } else { double *doublePtr = (double *)item2.data; printf("Value: %lf\n", *doublePtr); } return 0; }

In this example, we use a structure to store data of different types in a heterogeneous data structure.


Why we use void pointers?


Void pointers (void *) are used in C for their flexibility and ability to work with various data types. Here are some examples to illustrate why and how void pointers are used:

1. Dynamic Memory Allocation:


c
#include <stdio.h> #include <stdlib.h> int main() { int *intPtr; double *doublePtr; // Allocate memory for an integer void *ptr = malloc(sizeof(int)); if (ptr == NULL) { perror("Memory allocation failed"); return 1; } // Cast the void pointer to an integer pointer intPtr = (int *)ptr; // Allocate memory for a double ptr = malloc(sizeof(double)); if (ptr == NULL) { perror("Memory allocation failed"); free(intPtr); // Clean up previous allocation return 1; } // Cast the void pointer to a double pointer doublePtr = (double *)ptr; // Now, you can use intPtr and doublePtr to access allocated memory // Don't forget to free the allocated memory free(intPtr); free(doublePtr); return 0; }


Void pointers are used to allocate memory for different data types, and you cast them to the appropriate data type after allocation.

2. Generic Functions:


c
#include <stdio.h> void printValue(void *ptr, char type) { if (type == 'i') { int *intPtr = (int *)ptr; printf("Value: %d\n", *intPtr); } else if (type == 'd') { double *doublePtr = (double *)ptr; printf("Value: %lf\n", *doublePtr); } } int main() { int intValue = 42; double doubleValue = 3.14159; printValue(&intValue, 'i'); // Prints: Value: 42 printValue(&doubleValue, 'd'); // Prints: Value: 3.141590 return 0; }


Void pointers allow you to create generic functions that can work with different data types. In this example, the printValue function can print values of integers or doubles based on the specified type.

3. Heterogeneous Data Structures:


c
#include <stdio.h> struct GenericItem { void *data; int type; // 0 for int, 1 for double }; int main() { struct GenericItem item1, item2; int intValue = 42; double doubleValue = 3.14159; item1.data = &intValue; item1.type = 0; item2.data = &doubleValue; item2.type = 1; printf("Item 1: "); if (item1.type == 0) { int *intPtr = (int *)item1.data; printf("Value: %d\n", *intPtr); } else { double *doublePtr = (double *)item1.data; printf("Value: %lf\n", *doublePtr); } printf("Item 2: "); if (item2.type == 0) { int *intPtr = (int *)item2.data; printf("Value: %d\n", *intPtr); } else { double *doublePtr = (double *)item2.data; printf("Value: %lf\n", *doublePtr); } return 0; }

Void pointers can be used to create data structures that store elements of different data types, making them suitable for scenarios where you need mixed data types within the same structure.

Post a Comment

0 Comments