Pourquoi l’adresse du tableau n’est-elle pas convertible en ** en C ?

la programmation


Bonjour. Pourquoi l’adresse du tableau (c’est-à-dire &) non convertible en ** en C ?

Ce que j’ai essayé :

J’ai essayé ce qui suit..

C
#include <stdio.h>


int main()
{
    int** a;
    int b[5];
    b[1] = 123;
    
    //a = &b; //< results in output of warning "assignment to ‘int **’ from incompatible pointer type ‘int (*)[5]’"
    int* c = b;
    a = &c; //< this works
    printf("*a is %i\n", (*a)[1]);
    
    return 0;
}

Je m’attendrais à cela, comme b peut être converti en int*il serait possible de convertir &b à int**. Cependant, cela entraîne l’avertissement mentionné dans le bloc de code ci-dessus.

Utiliser mingw gcc sur Windows ceci (écrire puis lire à partir d’un ** qui a été attribué à l’adresse d’un tableau) a effectivement fonctionné une fois mais pas une deuxième fois.

Solution 1

b est un tableau : le nom d’un tableau est un pointeur vers le premier élément, donc techniquement, &b est un pointeur vers un pointeur vers un entier. Mais… votre compilateur n’est pas d’accord car il considère (à juste titre) qu’il s’agit d’un pointeur vers un tableau d’entiers. Et les tableaux sont un sucre syntaxique pour l’arithmétique des pointeurs en arrière-plan, ils ne fonctionnent donc pas comme vous pourriez le penser.
Vous pouvez contourner ce problème en faisant b un pointeur vers un int à la place :

C
#include <stdio.h>
#include <malloc.h>
int main()
    {
    int** a;
    int* b = malloc(sizeof(int) * 5);
    b[1] = 123;
    
    a = &b; 
    printf("*a is %i\n", (*a)[1]);

    free(b);
    return 0;
    }

Solution 2

Un tel avertissement signifie que vous devez définir explicitement le type de casting résultant, ce qui signifie que vous comprenez que le résultat de l’utilisation d’une telle variable dans le code peut provoquer un crash ou des fuites de mémoire. À titre d’exemple, le code des commentaires de cette discussion https://www.codeproject.com/Answers/5370174/C-langage-I-dont-understand-multi-dimensionnel-arr#answer3[^]:

int mat[3][3] = { {0,1,2},{3,4,5},{6,7,8} };
int **ptr = (int **)&mat;
printf("%d\n", mat[1][1]); /* prints "4" */
printf("%d\n", ptr[1][1]); /* seg faults! */ 

Ici, vous avez un tableau multidimensionnel et vous le convertissez en int**. Ce code fonctionnera sur la plateforme x86 et plantera sur x64 à l’endroit spécifié dans le commentaire.

Ainsi, l’avertissement de diffusion vous montre simplement que vous devez prendre en compte la variable résultante de l’utilisation – c’est tout.

コメント

タイトルとURLをコピーしました