The void pointer, also known as the generic pointer, is a special type of pointer that can be pointed at objects of any data type! A void pointer is declared like a normal pointer, using the void keyword as the pointer’s type:
void *pVoid; // pVoid is a void pointer
A void pointer can point to objects of any data type:
int nValue;
float fValue;
struct Something
{
int nValue;
float fValue;
};
Something sValue;
void *pVoid;
pVoid = &nValue; // valid
pVoid = &fValue; // valid
pVoid = &sValue; // valid
However, because the void pointer does not know what type of object it is pointing to, it can not be dereferenced! Rather, the void pointer must first be explicitly cast to another pointer type before it is dereferenced.
int nValue = 5; void *pVoid = &nValue; // can not dereference pVoid because it is a void pointer int *pInt = static_cast<int*>(pVoid); // cast from void* to int* cout << *pInt << endl; // can dereference pInt
Similarly, it is not possible to do pointer arithmetic on a void pointer. Note that since void pointers can’t be dereferenced, there is no such thing as a void reference.
The next obvious questions is: If a void pointer doesn’t know what it’s pointing to, how do we know what to cast it to? Ultimately, that is up to you to keep track of.
Here’s an example of a void pointer in use:
#include <iostream>
enum Type
{
INT,
FLOAT,
STRING,
};
void Print(void *pValue, Type eType)
{
using namespace std;
switch (eType)
{
case INT:
cout << *static_cast<int*>(pValue) << endl;
break;
case FLOAT:
cout << *static_cast<float*>(pValue) << endl;
break;
case STRING:
cout << static_cast<char*>(pValue) << endl;
break;
}
}
int main()
{
int nValue = 5;
float fValue = 7.5;
char *szValue = "Mollie";
Print(&nValue, INT);
Print(&fValue, FLOAT);
Print(szValue, STRING);
return 0;
}
This program prints:
5 7.5 Mollie
In general, it is a good idea to avoid using void pointers unless absolutely necessary, as they effectively allow you to avoid type checking. This allows you to inadvertently do things that make no sense, and the compiler won’t complain about it. For example, the following would be valid:
Print(&nValue, STRING);
But who knows what the result would actually be!
Although the above function seems like a neat way to make a single function handle multiple data types, C++ actually offers a much better way to do the same thing (via function overloading) that retains type checking to help prevent misuse. Many other places where void pointers would once be used to handle multiple data types are now better done using templates, which also offer strong type checking.
However, very occasionally, you may still find a reasonable use for the void pointer. Just make sure there isn’t a better (safer) way to do the same thing using other language mechanisms first!
7.1 — Function parameters and arguments
|
Index
|
6.12 — References vs. pointers, and member selection
|
7.1 — Function parameters and arguments
Index
6.12 — References vs. pointers, and member selection
Void pointers used in custom memory allocators as well – malloc, CoTaskMemAlloc, etc.. Memory allocation routines usually don’t aware of data types they allocating memory for.
–serg
Note that C++ offers “new” as a type-safe way to allocate memory instead of the C malloc(). Also note that C++ offers many containers and constructs that eliminate the need for explicit new anyways, e.g.:
Instead of:
V
[...] 6.13 — Void pointers [...]
is there any reason for using pointer(*) for char but reference (&) for float and int?
int main() { int nValue = 5; float fValue = 7.5; char *szValue = "Mollie"; // here you used pointer Print(&nValue, INT); Print(&fValue, FLOAT); Print(szValue, STRING); return 0; }I used a pointer in the char declaration because it’s an array of chars, not just a normal char. You can also declare it like this:
The Print() function takes a pointer as it’s first argument. In this context, the & is used to pass the address of a normal variable to a pointer parameter.
So you can’t do this? =[
Thank you very much for your tutorials!
Ok you can’t =D
I use a wide variety of materials to learn from, but this site alway cleans up the problems or questions. ty :)
R u working professional or a student ?
is dangling pointer and void pointer same
ya i agree 2 wit Henry..it clears up problm or doubt to teh root of it..R u working Henry??
hey can anyone tell wats a dangling pointer .is it d same thing as void /Null pointer
is it alright to dereferenced like this *(static_cast(pointerVariable));
Alex,
I’m a new user to your site. IT IS AWESOME!! I will be visiting it often. Thanks for all your hard work.
AB
Congratulations for your site. It is really helpful.
It would be very helpful to have some practice (e.g. programs to write) with pointers and dynamic memory allocation here!
But thanks for a wonderful site Alex! Really fun.
[...] learn more about void pointers, take a look at 6.13 — Void pointers. Tagged: cquestionsunsigned-charvoid-pointers /* * * CONFIGURATION VARIABLES: EDIT [...]
why when you use:
cout << static_cast(pValue) << endl; // without the (*) symbol, you get the whole word "molly", unlike the case you do the same but with an int type pointer, and get the direction that it is point to?
char *szValue = "Mollie"; // here you used pointer
or
char szValue[] = "Mollie";
cout<<szValue1<<endl; // it gives "mollie"
int numbers[5]={'1','2','3','4','5' };
cout<<numbers; // it gives 0x28fefc