OneZero
OneZero

Reputation: 11914

What does void* mean and how to use it?

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?

Upvotes: 218

Views: 253955

Answers (11)

Mathav Krishnan
Mathav Krishnan

Reputation: 1

As it turns out it is also possible that the size of a pointer can vary depending on the data type of the object to which it points. Thus, as with integers where you can run into trouble attempting to assign a long integer to a variable of type short integer, you can run into trouble attempting to assign the values of pointers of various types to pointer variables of other types.

To minimize this problem, C provides for a pointer of type void. We can declare such apointer by writing:

void *ptr;

while C will not permit the comparison of a pointer to type integer with a pointer to type character, for example,either of these can be compared to a void pointer.

Upvotes: 0

Friedrich
Friedrich

Reputation: 6006

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

Upvotes: 26

John Bode
John Bode

Reputation: 123596

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.

Upvotes: 250

Jeyaram
Jeyaram

Reputation: 9504

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);
}

Upvotes: 3

dilara
dilara

Reputation: 17

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

Upvotes: -4

md5
md5

Reputation: 23727

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.

Upvotes: 2

mathematician1975
mathematician1975

Reputation: 21351

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.

Upvotes: 1

TheSteve
TheSteve

Reputation: 1168

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));

Upvotes: 30

A.G.
A.G.

Reputation: 1319

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.

Upvotes: 3

glglgl
glglgl

Reputation: 91159

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

Upvotes: -1

Ren&#233; Kolař&#237;k
Ren&#233; Kolař&#237;k

Reputation: 1284

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.

Upvotes: 11

Related Questions