203

Today when I was reading others' code, I saw something like void *func(void* i);, what does this void* mean here for the function name and for the variable type, respectively?

In addition, when do we need to use this kind of pointer and how to use it?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
OneZero
  • 11,556
  • 15
  • 55
  • 92
  • 3
    What C book are you using ? You're asking for the better part of an entire chapter. – cnicutar Jul 24 '12 at 08:16
  • 1
    Have a look at http://stackoverflow.com/questions/692564/concept-of-void-pointer-in-c-programming – WDan Jul 24 '12 at 08:21
  • Its answered before: http://stackoverflow.com/questions/1043034/what-does-void-mean-in-c-c-and-c and here: http://stackoverflow.com/questions/7324860/using-void-in-c – d33pika Jul 24 '12 at 08:21
  • [http://stackoverflow.com/search?q=void*+%5Bc%5D](http://stackoverflow.com/search?q=void*+%5Bc%5D) http://stackoverflow.com/questions/2590314/what-are-the-reasons-for-casting-a-void-pointer – Danny Varod Jul 24 '12 at 08:26
  • Take a cue from `malloc` and `calloc`. The man page goes on to say: "...return a pointer to the allocated memory, which is suitably aligned for any built-in data type." – automaton May 28 '16 at 20:48

10 Answers10

237

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 ints, but is actually working with doubles. There's no way to catch this problem at compile time; you'll just wind up with a missorted array.

rassar
  • 5,412
  • 3
  • 25
  • 41
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 9
    It's actually not guaranteed that a `void*` can be cast to a function pointer. But for data pointers what you said holds. – Vatine Jul 12 '16 at 10:52
  • 1
    Before void pointers were available "char *" was used instead. But void is better as it cannot actually be used to alter anything directly. – user50619 Jun 04 '19 at 13:08
  • Similar like generics in Java? – Gaurav Khare Jun 07 '23 at 19:23
  • @GauravKhare: Not...really. Java generics, like C++ templates, are a language feature designed to support true type polymorphism. Void pointers are a *hack* to kind-of-sort-of fake type polymorphism. – John Bode Jun 10 '23 at 16:22
29

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));
TheSteve
  • 1,138
  • 6
  • 12
  • 1
    So that's pretty much like generics in other languages, but with no type checking, right? – wingerse Aug 25 '16 at 14:05
  • 6
    I suppose it would be similar, however since there is no type checking, making a mistake can cause very strange results or cause the program to outright crash. – TheSteve Aug 28 '16 at 23:58
22

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".

Chris Tang
  • 567
  • 7
  • 18
Friedrich
  • 5,916
  • 25
  • 45
9
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.

René Kolařík
  • 1,244
  • 1
  • 10
  • 18
3

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.

A.G.
  • 1,279
  • 1
  • 11
  • 28
3

A void pointer is known as generic pointer. I would like to explain with a sample pthread scenario.

The thread function will have the prototype as

void *(*start_routine)(void*)

The pthread API designers considered the argument and return values of thread function. If those thing are made generic, we can type cast to void* while sending as argument. similarly the return value can be retrieved from void*(But i never used return values from thread function).

void *PrintHello(void *threadid)
{
   long tid;

   // ***Arg sent in main is retrieved   ***
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      //*** t will be type cast to void* and send as argument.
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);   
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }    
   /* Last thing that main() should do */
   pthread_exit(NULL);
}
Jeyaram
  • 9,158
  • 7
  • 41
  • 63
2

C11 standard (n1570) §6.2.2.3 al1 p55 says :

A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.

You can use this generic pointer to store a pointer to any object type, but you can't use usual arithmetic operations with it and you can't deference it.

md5
  • 23,373
  • 3
  • 44
  • 93
1

a void* is a pointer, but the type of what it points to is unspecified. When you pass a void pointer to a function you will need to know what its type was in order to cast it back to that correct type later in the function to use it. You will see examples in pthreads that use functions with exactly the prototype in your example that are used as the thread function. You can then use the void* argument as a pointer to a generic datatype of your choosing and then cast it back to that type to use within your thread function. You need to be careful when using void pointers though as unless you case back to a pointer of its true type you can end up with all sorts of problems.

mathematician1975
  • 21,161
  • 6
  • 59
  • 101
0

The function takes a pointer to an arbitrary type and returns one such.

glglgl
  • 89,107
  • 13
  • 149
  • 217
-4

it means pointer you can use this link to get more info about pointer http://www.cprogramming.com/tutorial/c/lesson6.html

dilara
  • 19
  • 10