Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between (void **)&x and (void *)x?

What is the difference between (void **)&x and (void *)x? I will give you some code, please help me out.

float *xd;
int size=width*width*size(float);
cudaMalloc((void **)&x,size); 1
cudaMalloc((void *)x,size);   2
cudaMalloc(&x,size);          3
cudaMalloc(*x,size);          4

cudaFree(xd);

I just want to know the difference.

The first parameter of the cudaMalloc() function is the address of a pointer variable that must point to the allocated object after allocation. The address of the pointer variable should be cast to (void **) because the function expects a generic pointer value; the memory allocation function is a generic function that is not restricted to any particular type of objects. This address allows the cudaMalloc() function to write the address of the allocated object into the pointer variable.3 The second parameter of the cudaMalloc() function gives the size of the object to be allocated, in terms of bytes. The usage of this second parameter is consistent with the size parameter of the C malloc() function.

like image 957
Prithvi Krishna Avatar asked Nov 23 '25 10:11

Prithvi Krishna


2 Answers

They're just about completely different.

This:

(void **)&x

takes the address of x and converts it to void** (pointer to pointer to void).

This:

(void *)x

takes the value of x and converts it to void*.

They're both pointers, but they point to entirely different locations in memory (unless x happens to contain its own address), and they're of different types.

And if you want to show us code, it would be helpful to show us code that actually compiles. Copy-and-paste your actual source code; don't re-type it. You haven't shown us the declaration of x (is xd a typo for x?), and size(float) is a syntax error (did you mean sizeof(float)?).

like image 115
Keith Thompson Avatar answered Nov 26 '25 17:11

Keith Thompson


To give you a better understanding why with cudaMalloc you often write (void**)&var, consider the following:

cudaMalloc allocates a memory on the GPU. The memory type it is referred is void* as it does not really care about the data type.

Once we have the address of that memory inside the cudaMalloc we just allocated, we need to somehow return it to the caller. But all CUDA API functions are returning error codes (or success code) and any additional returned data has to be passed back by parameter reference.

C language has no pass-by-reference, so you actually need to pass a pointer to a variable where you want the function to store the result. Since you want to store a pointer value, you need to pass a pointer-to-pointer. Hence void** type.

If one wanted to encapsulate a malloc in similar way, one would write something like this:

void myMalloc(void** ret, size_t size) {
    void* mem = malloc(size);
    *ret = mem;
}

Now, if you pass (void**)&var to myMalloc, the function will be able to overwrite the value of the var --- as ret will be pointing to var variable.

Does this make it clearer?

like image 25
CygnusX1 Avatar answered Nov 26 '25 17:11

CygnusX1



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!