不兼容的指针类型(双指针)

时间:2017-11-13 20:52:32

标签: c pointers double-pointer

在一个要求像这样的双指针的函数中:

#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);
}

所以我的问题是,为什么它适用于简单的指针,但它不适用于双指针(或者我猜更多)?

2 个答案:

答案 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 **的指针的隐式转换。