我有一个创建指针数组的函数。分配内存的函数通过传递给函数的参数返回新的内存指针。可以重现问题的最简单的代码如下:
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;
}
我可以将传递给foo的第一个参数转换为如此:'(void **)& ptr_arr'以消除警告,但是,我想知道:是否有更合适的解决方案?
答案 0 :(得分:0)
问题是你正在获取双指针的地址并将其传递给双指针参数。获取值的地址会创建一个指针,因此您最终会使用三重指针int***
,这就是您收到错误的原因。
将结果投射到void**
在技术上可以在这里工作,尽管它接近于类型系统上的滥用。
答案 1 :(得分:0)
问题是ptr_arr已经是int **,
当您执行&ptr_arr
时,它会显示为int ***
,因此您所做的不正确。
所以,如果你打算传递int **
另外,我觉得你的代码可以很好地进行清理。你的方法似乎是错误的。
答案 2 :(得分:0)
虽然保证从int *
转换为void *
,但从int **
转换为void **
并不能保证这一转换。要考虑这可能是什么原因,请考虑int *
实际上可能小于void *
。因此,使用void **
指针遍历int *
的数组将走错路并得到错误的数据。此外,我们无法保证int *
将使用与void *
相同的表示形式,只能保证在它们之间进行转换。
在实践中,我不知道任何会失败的机器。但标准并不保证。
编辑:eek,以及大家对传递int ***
的看法。但即使您通过int **
,上述内容仍适用。
EDIT2:comp.lang.c常见问题解答中有一个excellent discussion。