开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜