web-dev-qa-db-fra.com

C Double pointeur sur la structure

J'essaie d'élaborer un double pointeur sur une structure en C et je ne peux pas comprendre ce qui ne va pas ...

typedef struct
{
    int member;
} mystruct;

void myfunc(mystruct **data)
{
    (*data)->member = 1;
}

void main(int argc, char *argv[])
{
    mystruct **data;

    myfunc(data);

    printf("member = %d\n", (*data)->member);
}

Une question similaire a été posée ici: Comment travailler avec pointeur à pointeur sur structure en C? sur comment modifier un membre d'une structure via un double pointeur. La solution était la syntaxe (*data)->member = 1; qui a du sens. Mais dans ma petite application ici, je reçois une erreur de segmentation lors de l'exécution de cette ligne. Qu'est-ce que je fais mal? 

Merci

21
linsek

Vous devez indiquer quelque chose si vous voulez déréférencer un pointeur. Essaye ça:

void main(int argc, char *argv)
{
    mystruct actualThing;
    mystruct *pointer = &actualThing;
    mystruct **data = &pointer;
    myfunc(data);

    printf("Member: %d", (*data)->member);
}
18
DwB

Vous avez reçu une erreur de segmentation parce que vous n'avez pas alloué de structure.

La valeur de data est garbage. Elle pointe donc vers un emplacement en mémoire qui n'est pas la propriété de votre processus ou qui est inaccessible.

Vous devez d'abord allouer un objet de type mystruct. Voici un exemple de travail pour vous: http://ideone.com/XIdJ8

7
Ray Toal

data n'est pas initialisé et ne pointe donc pas vers une adresse mémoire sensible. De plus, il n'y a pas de structure mystruct flottant, il n'y a donc vraiment aucune donnée sensible à pointer. Pour votre exemple, vous voulez:

  1. Créez une mystruct.
  2. Faites un pointeur vers elle.
  3. Faites un pointeur sur ce pointeur.
5
gspr

Si vous devez seulement passer le pointeur double à une fonction de bibliothèque, vous n'avez pas besoin de créer de variable pour cela. Vous créez une variable de pointeur normale, vous l'initialisez pour pointer sur la mémoire appropriée (si la fonction le requiert), puis vous transmettez l'adresse du pointeur (créant ainsi le double pointeur "à la volée").

Je n'ai jamais utilisé libusb, je vais donc donner un exemple utilisant une fonction de bibliothèque standard. De la page de manuel:

   #include <stdlib.h>

   long int strtol(const char *nptr, char **endptr, int base);

Cela ne fait que ressemble à un double pointeur. C'est vraiment un pointeur unique simulé-passer par référence. Permettre à la fonction de renvoyer des informations supplémentaires en plus de sa valeur de retour normale. strtol renvoie un entier long, mais il peut également vous indiquer à quel moment le contenu de la chaîne a cessé de ressembler à un nombre.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *str = "99RED BALLOONS";
    char *what;
    long num;

    num = strtol(str, &what, 10);
    printf("Quantity: %ld;    Description: %s;\n", num, what);

    return 0;
}

Sortie:

Quantity: 99;    Description: RED BALLOONS;
1
luser droog

Vous lui passez un pointeur, mais le pointeur ne pointe rien.

Cela peut être plus utile:

void main(int argc, char *argv[])
{
    mystruct data;
    mystruct *ptr = &data;
    myfunc(&ptr);
    printf("member = %d\n", (*ptr)->member);
}
0
Chris Eberle