void**指针和void*[]作为函数参数

Uri*_*erg 5 c arrays pointers casting void-pointers

我收到以下警告: incompatible pointer types 'void**' and 'int* [2]'.

当我尝试编译以下代码时:

#include <stdlib.h>

void func1(void *arr[]) { }

int main() {
    int *arr[2];
    for (int i = 0; i < 5; i++) {
        arr[i] = (int*)malloc(sizeof(int));
        *(arr[i]) = 5;
    }
    func1(arr);
}
Run Code Online (Sandbox Code Playgroud)

现在,当我施放arr时它起作用,我(void**)找不到原因.此外我发现我还需要使用以下代码:

#include <stdlib.h>

void func1(void **arr) { }

int main() {
    int **arr;
    int i[] = { 1, 2 };
    int j[] = { 3, 4 };
    *arr = i;
    *(arr+1) = j;
    func1(arr); //Doesn't compile unless I use (void*) or (void**) casting
}
Run Code Online (Sandbox Code Playgroud)

我知道如果一个函数的参数是一个指向void我们可以传递给它的任何指针我们想要不进行转换,因为所有指针的大小都相同,那么为什么我不能以同样的方式将指针传递给指针呢?

Joh*_*ger 2

所有对象指针类型(包括int *)都保证可以与相互转换void *,但它们不能互换。类型的表示int *不必与类型的表示相同void *(尽管实际上,几乎总是如此),因此不会自动从指向int *(ie int **) 的指针转换为指向void *(ie void **) 的指针。假设一种类型的指向事物可以正确地重新解释为另一种指向类型的事物是不安全的。

顺便说一下,请注意:

如果函数的参数是指向 void 的指针,我们可以将任何我们想要的指针传递给它,而无需强制转换,因为所有指针的大小相同

是一个不正确的表征。指针不需要全部具有相同的大小。只要求每个对象指针都可以转换为类型void *并返回,并且这种往返转换的结果等于原始指针。

请牢记@Lundin 的评论:数组不是指针。尽管如此,在大多数情况下,数组类型的值确实会衰减为指针,包括当它们作为函数参数或赋值运算符的右侧操作数出现时。