numerical25
numerical25

Reputation: 10790

What does (void**) mean in C?

I would look this up, but honestly I wouldn't know where to start because I don't know what it is called. I've seen variables passed to functions like this:

myFunction((void**)&variable);

Which confuses the heck out of me cause all of those look familiar to me; I've just never seen them put together like that before.

What does it mean? I am a newb so the less jargon, the better, thanks!

Upvotes: 18

Views: 14470

Answers (6)

Kim Reece
Kim Reece

Reputation: 1280

Take it apart piece by piece...

myFunction takes a pointer to a pointer of type void (which pretty much means it could point to anything). It might be declared something like this:

myFunction(void **something);

Anything you pass in has to have that type. So you take the address of a pointer, and cast it with (void**) to make it be a void pointer. (Basically stripping it of any idea about what it points to - which the compiler might whine about otherwise.)

This means that &variable is the address (& does this) of a pointer - so variable is a pointer. To what? Who knows!

Here is a more complete snippet, to give an idea of how this fits together:

#include <stdio.h>

int myInteger = 1;
int myOtherInt = 2;
int *myPointer = &myInteger;

myFunction(void **something){
    *something = &myOtherInt;
}

main(){
    printf("Address:%p Value:%d\n", myPointer, *myPointer);
    myFunction((void**)&myPointer);
    printf("Address:%p Value:%d\n", myPointer, *myPointer);
}

If you compile and run this, it should give this sort of output:

Address:0x601020 Value:1
Address:0x601024 Value:2

You can see that myFunction changed the value of myPointer - which it could only do because it was passed the address of the pointer.

Upvotes: 8

In silico
In silico

Reputation: 52129

It's a cast to a pointer to a void pointer.

You see this quite often with functions like CoCreateInstance() on Windows systems.

ISomeInterface* ifaceptr = 0;
HRESULT hr = ::CoCreateInstance(CLSID_SomeImplementation, NULL, CLSCTX_ALL,
    IID_ISomeInterface, (void**)&ifaceptr);
if(SUCCEEDED(hr))
{
    ifaceptr->DoSomething();
}

The cast converts the pointer to an ISomeInterface pointer into a pointer to a void pointer so that CoCreateInstance() can set ifaceptr to a valid value.

Since it is a pointer to a void pointer, the function can output pointers of any type, depending on the interface ID (such as IID_ISomeInterface).

Upvotes: 5

lach
lach

Reputation: 386

The variable is a pointer to something of undefined (void) type. The & operator returns the address of that variable, so you now have a pointer to a pointer of something. The pointer is therefore passed into the function by reference. The function might have a side effect which changes the memory referenced by that pointer. In other words, calling this function might change the something that the original pointer is referencing.

Upvotes: 0

EMP
EMP

Reputation: 61971

void* is a "pointer to anything". void ** is another level of indirection - "pointer to pointer to anything". Basically, you pass that in when you want to allow the function to return a pointer of any type.

&variable takes the address of variable. variable should already be some kind of a pointer for that to work, but it's probably not void * - it might be, say int *, so taking its address would result in a int **. If the function takes void ** then you need to cast to that type.

(Of course, it needs to actually return an object of the right type, otherwise calling code will fail down the track when it tries to use it the wrong way.)

Upvotes: 16

Brendan Long
Brendan Long

Reputation: 54242

It's a pointer to a pointer to a variable with an unspecified type. All pointers are the same size, so void* just means "a pointer to something but I have no idea what it is". A void** could also be a 2D array of unspecified type.

Upvotes: 3

James McNellis
James McNellis

Reputation: 355009

That casts &variable to a void** (that is, a pointer to a pointer to void).

For example, if you have something along the lines of

void myFunction(void** arg);

int* variable;

This passes the address of variable (that's what the unary-& does, it takes the address) to myFunction().

Upvotes: 2

Related Questions