Problem with incompatible types (double pointers)

3

I get the doubt having the following function that asks for a double pointer:

#include <stdlib.h>

void    prueba(void **ap)
{
    *ap = NULL;
}

with the following main:

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

When compiling, gcc takes out the following warning:

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

The doubt comes from that with simple pointers this does not happen, for example, with the following function and main respectively gcc compiles correctly, despite passing a pointer to char to a function that asks for a pointer void:

function:

#include <stdlib.h>

void    prueba(void *ap)
{
    ap = NULL;
}

main:

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

Why should it be possible with simple pointers but with double ones?

    
asked by latiagertrutis 13.11.2017 в 01:49
source

1 answer

0

In the first case when compiling a warning occurs because you are passing a data type (char **) to a (void **) , which are different types. But it's just a warning, the program compiles and works correctly.

If you want to avoid the warning you have to do casting like this:

prueba((void **)&str);

In this way you tell the compiler to convert the pointer (char **) to (void **) before passing it to the function, which expects precisely one (void **) and therefore does not give Warning for incompatibility of types.

In the second version of your code, where you use simple pointers, I do not know why it does not give Warning but be careful because it is incorrect and will not do what you expect. When using simple pointers the function tests NO will modify the variable str of the main, if not a local copy called ap, which in the end does nothing.

Let's see a simpler example with int variables. In the code below the value of the variable 'a' of the main is copied to the variable 'x' of the function 'test'. The key is that the value is copied, but a and x are independent variables . Therefore, when 'test' increases 'x' by 1, the variable 'a' is not affected in any way. That is, test as created here does not do anything useful.

void prueba(int x) {
    x = x + 1;
}

void main() {
    int a = 0;
    prueba(a); // le pasamos el valor de a
    printf("%d",a); // imprime 0, ¡mal!
}

The correct way to do this is to use pointers . Modify the code to pass to 'test' a pointer to integer, so that from 'test' we can directly access the memory area of the variable 'a'. So yes we increase the value of 'a' in 1.

void prueba(int *x) {
    *x = *x + 1; // modificamos la zona de memoria a la que apunta x
}

void main() {
    int a = 0;
    prueba(&a); // le pasamos la dirección de memoria de a
    printf("%d",a); // imprime 1, ¡bien!
}

Going back to the original case of your question, the variable 'str' you use is already a 'char *' pointer. To pass it to the test function and, as in the previous example, modify the variable 'str' of the main, you need to use a pointer to pointer, that is, a 'char **'. Otherwise the 'test' function will not do anything because instead of modifying the variable 'str' of the main it will simply modify a local copy independent of 'str'.

    
answered by 28.12.2018 в 14:00