IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Réallocation d'un pointeur de pointeurs


Sujet :

C

  1. #1
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut Réallocation d'un pointeur de pointeurs
    Bonjour,

    J'ai une structure node qui se présente ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    typedef struct s_node    t_node;
     
    struct                    s_node
    {
      int                     value;
    	t_node                  *parent;
    	int                     nb_children;
    	t_node                  **children;
    };
    Pour ajouter un pointeur à children, je fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    t_node *this;
     
    this->nbchildren++;
     
    children = realloc(children, this->nb_children * sizeof(int *));
    Or, ça me fait une erreur de segmentation. Est-ce que quelqu'un peut m'expliquer pourquoi?

    Merci

  2. #2
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    J'ai fait un exemple plus simple si vous voulez tester :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include <stdlib.h>
    #include <stdio.h>
     
    int main()
    {
      int **pp;
      int i;
     
      pp = malloc(7 * sizeof(int *));
     
      for (i = 0; i < 7; i++)
      {
        pp[i] = malloc(sizeof(int));
        (*pp)[i] = 7 - i;
        printf("(*pp)[%i] : %p\n", i, &(*pp)[i]);
      }
     
      pp = realloc(pp, 8 * sizeof(int *));
      pp[7] = malloc(sizeof(int));
      (*pp)[7] = 7 - i;
     
      for (i = 0; i < 8; i++)
        printf("(*pp)[%i] : %p\n", i, &(*pp)[i]);
     
      printf("\n");
     
      printf("%i\n", sizeof(*pp));
     
      return 0;
    }

  3. #3
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Code un peu revu, j'ai juste compilé et lancé et aucune erreur de segmentation mais je n'est pas testé plus loin. Le mieux est d'utiliser sizeof de la même manière que je l'ai mis.
    Par ailleurs, pour realloc, il est préférable d'utiliser un pointeur temporaire, comme ca lorsque la reallocation echoue le pointeur d'origine n'est pas changé, si ca reussi bin plus qu'à mettre à jour ton pointeur en faisant une simple affectation (voir le code)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include <stdlib.h>
    #include <stdio.h>
     
     
    int main (void)
    {
      int ** pp       = NULL;
      int ** pp_temp  = NULL;
      int    i        = 0;
     
     
      pp = malloc (7 * sizeof (* pp));
     
      for (i = 0; i < 7; i++)
      {
        pp[i] = malloc (sizeof (** pp));
        pp[i] = 7 - i;
        printf("(*pp)[%i] : %p\n", i, &(*pp)[i]);
      }
     
     
      pp_temp = realloc (pp, 8 * sizeof (* pp));
     
      if (! pp_temp)
      {
         /* Liberation de la memoire et fermeture du programme a faire. */
         /* ... */
      }
     
      pp = pp_temp;  /* --- Mise a jour du pointeur apres reallocation --- */
      pp[7] = malloc (sizeof (** pp));
      pp[7] = 7 - i;
     
     
     
      for (i = 0; i < 8; i++)
        printf("(*pp)[%i] : %p\n", i, &(*pp)[i]);
     
     
      printf("\n");
      printf("%i\n", sizeof(*pp));
     
      /*
       * NE PAS OUBLIER LA LIBERATION DE LA MEMOIRE !!
       */
     
      return EXIT_SUCCESS;
    }
    De plus, n'oublies pas la libération de la mémoire et surtout, n'oublies pas de tester tes retours de malloc etc...
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  4. #4
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    C'est quoi ce code???

    Est-ce que vous le tester avant de dire qu'il marche?

    Ceci, à la limite, je comprends pourquoi on peut passer à côté:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pp[i] = malloc(sizeof(int));
    (*pp)[i] = 7 - i;
    Mais celui là?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pp[i] = malloc (sizeof (** pp));
    pp[i] = 7 - i;
    Cela ne choque personne?

    Déjà, où sont les tests du retour de malloc?

    Lorsqu'on écrit du code réponse, on doit tout de même faire attention à ce qu'on fait. Je sais que tout le monde se trompe, je serais le premier à le dire (surtout le lundi ) mais les gens vont copier-coller et appliquer ce genre de code...

    L'instruction correcte est:


    Jc

  5. #5
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    Tu as commis une petite erreur dans le code corrigé, tu as initialisé un pointeur par un int (pp[i] = 7 - i. J'ai corrigé le problème en supprimant les parenthèses (*pp[i] = 7 - i et maintenant ça marche.

    Merci pour l'idée du pointeur temporaire, je n'y avais pas pensé.

    Code qui fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #include <stdlib.h>
    #include <stdio.h>
     
    int main()
    {
      int ** pp       = NULL;
      int ** pp_temp  = NULL;
      int    i        = 0;
     
     
      pp = malloc (7 * sizeof (int *));
     
      for (i = 0; i < 7; i++)
      {
        pp[i] = malloc (sizeof (int));
        *pp[i] = i;
        printf("*pp[%i] : %i\n", i, *pp[i]);
      }
     
     
      pp_temp = realloc (pp, 8 * sizeof (** pp));
     
      if (! pp_temp)
      {
         /* Liberation de la memoire et fermeture du programme a faire. */
         /* ... */
      }
     
      pp = pp_temp;
      pp[7] = malloc (sizeof (int));
      *pp[7] = i;
     
     
     
      for (i = 0; i < 8; i++)
        printf("*pp[%i] : %i\n", i, *pp[i]);
     
      /* Libérer la mémoire ... */
     
      return 0;
    }

  6. #6
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    Citation Envoyé par fearyourself
    C'est quoi ce code???

    L'instruction correcte est:

    Merci, je l'ai remarqué juste apres

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Ha oups, c'est vrai j'ai fait une petite boulette, j'ai même pas fait attention à cette erreur ca m'apprendra à corriger un peu trop vite, mille excuses
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Trunks
    J'ai fait un exemple plus simple si vous voulez tester :
    Ah ! Voilà ce qui s'appelle "réduire le code au minimum compilable montrant le probléme". C'est bien.

    Pour le code, tu utilises des syntaxes trop complexes et non maitrisées (parenthèses mal placées). Il faut rester simple. D'autre part, il faut vérifier les allocations, utiliser realloc() correctement, libérer...

    http://emmanuel-delahaye.developpez....tes.htm#malloc
    http://emmanuel-delahaye.developpez....es.htm#realloc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    #include <stdlib.h>
    #include <stdio.h>
     
    int main()
    {
       int n = 7;
       int **pp = malloc(n * sizeof * pp);
     
       if (pp != NULL)
       {
          /* allocation */
          {
             int i;
             for (i = 0; i < n; i++)
             {
                pp[i] = malloc(sizeof * pp[i]);
             }
          }
     
          /* remplissage */
          {
             int i;
             for (i = 0; i < n; i++)
             {
                *pp[i] = n - i;
             }
          }
     
          /* affichage */
          {
             int i;
             for (i = 0; i < n; i++)
             {
                printf("pp[%d]=%p *pp[%d]=%d\n", i, pp[i], i, *pp[i]);
             }
             printf("\n");
          }
     
          /* tentative d'agrandissement */
          {
             void* tmp = realloc (pp, (n + 1) * sizeof * pp);
     
             if (tmp != NULL)
             {
                /* confirmation */
                n++;
                pp = tmp;
                pp[n - 1] = malloc(sizeof(int));
                *pp[n - 1] = 0;
     
                /* affichage */
                {
                   int i;
                   for (i = 0; i < n; i++)
                   {
                      printf("pp[%d]=%p *pp[%d]=%d\n", i, pp[i], i, *pp[i]);
                   }
                   printf("\n");
                }
                /* liberation */
                {
                   int i;
                   for (i = 0; i < n; i++)
                   {
                      free (pp[i]), pp[i] = NULL;
                   }
                }
             }
          }
          free (pp), pp = NULL;
       }
     
       return 0;
    }
    Voilà du code prêt à être 'modularisé' en fonctions.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre averti Avatar de Trunks
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2004
    Messages
    534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2004
    Messages : 534
    Points : 412
    Points
    412
    Par défaut
    Merci beaucoup

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Pointeurs et pointeurs de pointeurs
    Par wallace27 dans le forum C
    Réponses: 10
    Dernier message: 09/04/2015, 22h07
  2. Réponses: 21
    Dernier message: 06/08/2009, 09h31
  3. Réponses: 6
    Dernier message: 26/05/2007, 00h33
  4. pointeur de pointeur
    Par petdelascar dans le forum C
    Réponses: 2
    Dernier message: 05/12/2005, 10h26
  5. pointeur sur pointeur
    Par gaut dans le forum C
    Réponses: 3
    Dernier message: 01/11/2005, 21h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo