What does void* mean and how to use it?
A pointer to void
is a "generic" pointer type. A void *
can be converted to any other pointer type without an explicit cast. You cannot dereference a void *
or do pointer arithmetic with it; you must convert it to a pointer to a complete data type first.
void *
is often used in places where you need to be able to work with different pointer types in the same code. One commonly cited example is the library function qsort
:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
base
is the address of an array, nmemb
is the number of elements in the array, size
is the size of each element, and compar
is a pointer to a function that compares two elements of the array. It gets called like so:
int iArr[10];
double dArr[30];
long lArr[50];
...
qsort(iArr, sizeof iArr/sizeof iArr[0], sizeof iArr[0], compareInt);
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareDouble);
qsort(lArr, sizeof lArr/sizeof lArr[0], sizeof lArr[0], compareLong);
The array expressions iArr
, dArr
, and lArr
are implicitly converted from array types to pointer types in the function call, and each is implicitly converted from "pointer to int
/double
/long
" to "pointer to void
".
The comparison functions would look something like:
int compareInt(const void *lhs, const void *rhs)
{
const int *x = lhs; // convert void * to int * by assignment
const int *y = rhs;
if (*x > *y) return 1;
if (*x == *y) return 0;
return -1;
}
By accepting void *
, qsort
can work with arrays of any type.
The disadvantage of using void *
is that you throw type safety out the window and into oncoming traffic. There's nothing to protect you from using the wrong comparison routine:
qsort(dArr, sizeof dArr/sizeof dArr[0], sizeof dArr[0], compareInt);
compareInt
is expecting its arguments to be pointing to int
s, but is actually working with double
s. There's no way to catch this problem at compile time; you'll just wind up with a missorted array.
Using a void * means that the function can take a pointer that doesn't need to be a specific type. For example, in socket functions, you have
send(void * pData, int nLength)
this means you can call it in many ways, for example
char * data = "blah";
send(data, strlen(data));
POINT p;
p.x = 1;
p.y = 2;
send(&p, sizeof(POINT));
C is remarkable in this regard. One can say void
is nothingness void*
is everything (can be everything).
It's just this tiny *
which makes the difference.
Rene has pointed it out. A void *
is a Pointer to some location. What there is how to "interpret" is left to the user.
It's the only way to have opaque types in C. Very prominent examples can be found e.g in glib or general data structure libraries. It's treated very detailed in "C Interfaces and implementations".
I suggest you read the complete chapter and try to understand the concept of a pointer to "get it".
void*
is a 'pointer to memory with no assumptions what type is there stored'. You can use, for example, if you want to pass an argument to function and this argument can be of several types and in function you will handle each type.
You can have a look at this article about pointers http://www.cplusplus.com/doc/tutorial/pointers/ and read the chapter : void pointers.
This also works for C language.
The void type of pointer is a special type of pointer. In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereference properties).
This allows void pointers to point to any data type, from an integer value or a float to a string of characters. But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some other pointer type that points to a concrete data type before dereferencing it.