Pointer mismatch for actual parameter?
I have a function which creates an array of pointers. The function which allocates the memory returns the new memory pointer through a parameter passed to the function. The simplest code which can reproduce the problem is as follows:
void foo (void** new_mem, size_t bytes)
{
*new_mem = malloc(bytes);
}
int main (void)
{
int** ptr_arr; // Want to create an array of pointers
foo(&ptr_arr, sizeof(int*)*100); // Create an array size of 100
// compiler emits warning:
// 'void **' differs in levels of indirection from 'int ***'
return 0;
}
I could cast the first parameter passed to fo开发者_开发问答o like so: '(void**)&ptr_arr' to get rid of the warning, however, I'm wondering: Is there a more appropriate solution?
Although there's a guaranteed conversion from int *
to void *
, there's no such guarantee for converting from int **
to void **
. To think about why this might be, consider that an int *
might actually be smaller than a void *
. As a result, using a void **
pointer to walk over an array of int *
s will walk the wrong stride and get the wrong data. Furthermore, there's no guarantee that int *
will use the same representation as void *
, only that there is a way to convert between them.
In practice, I don't know of any machines where this will fail. But it's not guaranteed by the standard.
EDIT: eek, and what everyone says about passing an int ***
. But even if you pass an int **
, the above still applies.
EDIT2: the comp.lang.c FAQ has an excellent discussion about this.
The problem is you're taking the address of a double pointer and passing it to a double pointer parameter. Taking the address of a value creates a pointer so you end up really with a triple pointer int***
which is why you get the error.
Casting the result to void**
will technically work here although it is bordering on an abuse on the type system.
The trouble is ptr_arr is already an int **,
when you do an &ptr_arr
, it will show as int ***
, so what you are doing is incorrect.
So, you can just pass ptr_arr if your intention is to pass an int **
Also, I feel your code can do well with a cleanup. Your approach seems to be wrong.
精彩评论