Reputation: 8146
I have to implement a wrapper for malloc
called mymalloc
with the following signature:
void mymalloc(int size, void ** ptr)
Is the void**
needed so that no type casting will be needed in the main program and the ownership of the correct pointer (without type cast) remains in main()
.
void mymalloc(int size, void ** ptr)
{
*ptr = malloc(size) ;
}
main()
{
int *x;
mymalloc(4,&x); // do we need to type-cast it again?
// How does the pointer mechanism work here?
}
Now, will the pointer being passed need to be type-cast again, or will it get type-cast implicitly?
I do not understand how this works.
Upvotes: 0
Views: 184
Reputation: 1186
void ** ptr
Here, "ptr" is a pointer to a pointer, and can be treated as a pointer to an array of pointers. Since your result is stored there (nothing returned from mymalloc), you need to clarify what you wish to allocate into "ptr". The argument "size" is not a sufficient description.
Upvotes: 0
Reputation: 477060
malloc
returns a void*
. For your function, the user is expected to create their own, local void*
variable first, and give you a pointer to it; your function is then expected to populate that variable. Hence you have an extra pointer in the signature, a dereference in your function, and an address-of operator in the client code.
The archetypal pattern is this:
void do_work_and_populate(T * result)
{
*result = the_fruits_of_my_labour;
}
int main()
{
T data; // uninitialized!
do_work_and_populate(&data); // pass address of destination
// now "data" is ready
}
For your usage example, substitute T = void *
, and the fruits of your labour are the results of malloc
(plus checking).
However, note that an int*
isn't the same as a void*
, so you cannot just pass the address of x
off as the address of a void pointer. Instead, you need:
void * p;
my_malloc(&p);
int * x = p; // conversion is OK
Upvotes: 3
Reputation: 145839
Contrary to void *
, the type void **
is not a generic pointer type so you need to cast before the assignment if the type is different.
Upvotes: 2