在一个要求像这样的双指针的函数中:
#include <stdlib.h>
void prueba(void **ap)
{
*ap = NULL;
}
使用以下主要编译:
#include <stdlib.h>
#include <stdio.h>
void prueba(void **ap);
int main(void)
{
char *str;
str = (char *)malloc(sizeof(char) * 5);
prueba(&str);
if (str == NULL)
printf("NULL");
return (0);
}
我通过gcc收到此警告:
main2.c:11:9: warning: incompatible pointer types passing 'char **' to parameter of type 'void **' [-Wincompatible-pointer-types]
prueba(&str);
^~~~
main2.c:4:23: note: passing argument to parameter 'ap' here
void prueba(void **ap);
但是,如果我使用简单的指针执行相同的操作,那就是向一个函数提供一个指向char的指针,该函数要求一个void指针,gcc编译时没有警告,例如,以下编译正确: 功能:
#include <stdlib.h>
void prueba(void *ap)
{
ap = NULL;
}
主:
#include <stdlib.h>
#include <stdio.h>
void prueba(void *ap);
int main(void)
{
char *str;
str = (char *)malloc(sizeof(char) * 5);
prueba(str);
if (str == NULL)
printf("NULL");
return (0);
}
所以我的问题是,为什么它适用于简单的指针,但它不适用于双指针(或者我猜更多)?
答案 0 :(得分:2)
可以自由地为任何对象指针自由分配void *
。这种自由不扩展到void **
,因为这是一种独特的类型。
此外,您的固定程序将无法按预期工作,因为ap = NULL;
仅更改prueba
内的局部变量,而不是传入的参数。
将原始程序更改为接受char **
而不是void **
。
答案 1 :(得分:2)
根据C标准(6.3.2.3指针)
1指向void的指针可以转换为指向any的指针 对象类型。指向任何对象类型的指针可以转换为 指向void并再次返回;结果应该等于 原始指针。
因此,在第二个代码片段中,类型char *
的指针被隐式转换为类型void *
,尽管该函数没有意义,因为它处理其参数的副本,因此不会改变原始指针。
但是void **
类型与类型void *
不同。因此引用不适用于类型void **
,并且编译器发出诊断消息,因为没有从指向任何对象类型的指针到类型为void **
的指针的隐式转换。