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 :

perte du pointeur sur une liste


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 251
    Par défaut perte du pointeur sur une liste
    Bonjour.
    J'ai un problème bizarre.
    Dans le code que je vous transmet ci dessous, je construis une liste d'éléments de type in.
    Je les stocke dans un pointeur, et j'accède à mes éléments grâce à un tableau dynamique.
    Ensuite je modifie ma liste. La nouvelle liste a le même nombre d'éléments que l'ancienne (en principe), et je modifie juste un élément.
    Ce qui est bizarre, c'est que lorsque la modification porte sur le premier élément, la liste retournée n'a plus le même nombre d'éléments. En fait, elle n'a aucun élément.
    Par contre lorsque je modifie n'importe quel autre élément (sauf le premier) j'ai le résultat attendu.

    Je vous transmet ci dessous un code minimal qui détaille le problème.

    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
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
    #include "stdafx.h"
    #include <stdio.h>
    #include <stdlib.h>
     
     
    typedef struct s_in
    {
    	int nombre; //il s'agit du compteur du nombre d'instance
    	int identifiant;
    }in;
     
    typedef in *p_in;
     
    //initialise un pointeur d'in
    p_in initialise_pointeur_in()
    {
    	p_in p = (p_in)malloc(sizeof(in));
    	if(p == NULL)
    	{
    		printf("\n initialisation de la liste d'in impossible \n");
    	}
    	else
    	{
    		p->identifiant = 0;
    		p->nombre = 0;
    	}
    	return p;
    }
     
    //initialise une in
    in initialise_in(int iden)
    {
    	in inst; 
    	inst.identifiant = iden;
    	inst.nombre = 0;
    	return inst;
    }
     
    //ajoute une in à un pointeur d'in
    p_in ajoute_in_pointeur_in(in ins, p_in pi)
    {
    	p_in p = (p_in)realloc(pi, (pi->nombre + 1)*sizeof(in));
    	if(p == NULL)
    	{
    		printf("\n ajout d'une nouvelle in à une liste d'in impossible \n");
    	}
    	else
    	{
    		p[p->nombre] = ins;
    		p->nombre++;
    		pi = p;
    	}
    	return pi;
    }
     
    //retourne la nouvelle liste d'instance quand l'instance ins a été traitée
    p_in nouvelle_liste(p_in pi, in ins)
    {
    	int j=0;
    	/*p_in p = initialise_pointeur_in();
    	while((pi[j].identifiant != ins.identifiant) && (j < pi->nombre))
    	{
    		p = ajoute_in_pointeur_in(pi[j], p);
    		j++;
    	}
    	if(pi[j].identifiant == ins.identifiant)
    	{
    		p = ajoute_in_pointeur_in(ins, p);
    		int i;
    		for(i=j+1; i<pi->nombre; i++)
    		{
    			p = ajoute_in_pointeur_in(pi[i], p);
    		}
    		return p;
    	}
    	else
    	{
    		return p;
    	}*/
    	for(j=0; j<pi->nombre; j++)
    	{
    		if(pi[j].identifiant == ins.identifiant)
    		{
    			pi[j] = ins;
    		}
    	}
    	return pi;
    }
     
    void affiche_liste_in(p_in p)
    {
    	int i;
    	for(i=0; i<p->nombre; i++)
    	{
    		printf("%d", p[i].identifiant);
    		printf("\n");
    	}
    }
     
    int main()
    {
    	p_in p = initialise_pointeur_in();
     
    	in ins1 = initialise_in(1);
    	in ins2 = initialise_in(2);
    	in ins3 = initialise_in(3);
    	in ins4 = initialise_in(4);
     
    	p = ajoute_in_pointeur_in(ins1, p);
    	p = ajoute_in_pointeur_in(ins2, p);
    	p = ajoute_in_pointeur_in(ins3, p);
    	p = ajoute_in_pointeur_in(ins4, p);
     
    	//les instructions commentées facilitent le test avec les autres instances 
     
    	affiche_liste_in(p);
    	printf("\n le nombre d'élements de la nouvelle liste avec l'instance1 est \n");
    	//printf("\n le nombre d'élements de la nouvelle liste avec l'instance2 est \n");
    	printf("%d \n", nouvelle_liste(p, ins1)->nombre);
    	//printf("%d \n", nouvelle_liste(p, ins2)->nombre);
    	printf("\n avec nouvelle liste sur instance1 \n");
    	//printf("\n avec nouvelle liste sur instance2 \n");
    	affiche_liste_in(nouvelle_liste(p, ins1));
    	//affiche_liste_in(nouvelle_liste(p, ins2));
     
    	free(p);
    	return 0;
    }
    D'avance merci pour le temps que vous m'accordez...

  2. #2
    Membre émérite Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Par défaut
    Ton code est très peu lisible.
    Ce que j'ai pu constater c'est que tu stockes le nombre des éléments dans le champ nombre du premier élément, donc il est tout à fait normale qu'avec :
    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
    <...>
    in initialise_in(int iden)
    {
        in inst
        inst.identifiant = iden;
        inst.nombre = 0;
        return inst;
    }
    <...>
    p_in nouvelle_liste(p_in pi, in ins)
    {
         int j=0;
         for(j=0; j<pi->nombre; j++)
         {
             if(pi[j].identifiant == ins.identifiant)
             {
                 pi[j] = ins;
             }
         }
         return pi;
    }
    <...>
    in ins1 = initialise_in(1);
    <...>
    p = ajoute_in_pointeur_in(ins1, p);
    <...>
    printf("%d \n", nouvelle_liste(p, ins1)->nombre);
    <...>
    Tu changes le nombre totale par 0.

    Je ne sais pas ce que tu cherches à faire, mais pour t'en rendre compte, force l'affichage ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void affiche_liste_in(p_in p)
    {
         int i;
         for(i=0; i<4; i++)
         {
             printf("%d", p[i].identifiant);
             printf("\n");
         }
    }

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 251
    Par défaut
    Merci pour ta réponse Mounir Orfi.
    J'ai bien compris ce que tu veux dire, et effectivement, quand je force l'affichage, j'obtiens bien ce que je désire.
    Ce que j'ai pu constater c'est que tu stockes le nombre des éléments dans le champ nombre du premier élément, donc il est tout à fait normale qu'avec :
    Tu changes le nombre totale par 0.
    Je me rends compte que c'est malheureusement ce qui se passe.
    En fait, pour moi nombre est un compteur que j'utilise pour parcourir les éléments de mon pointeur, que je considère ici comme un tableau dynamique.
    Comment je peux m'y prendre pour qu'elle (la variable nombre) ne me serve qu'à ça?
    Ou bien comment je peux contourner cette difficulté??
    D'avance merci.

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 251
    Par défaut
    J'ai modifié le code de la fonction nouvelle_liste ainsi:
    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
    p_in nouvelle_liste(p_in pi, in ins)
    {
    	int j=0;
    	int nbre = pi->nombre;
    	for(j=0; j<pi->nombre; j++)
    	{
    		if(pi[j].identifiant == ins.identifiant)
    		{
    			pi[j] = ins;
    		}
    	}
    	pi->nombre = nbre;
    	return pi;
    }
    J'obtiens maintenant ce que je désire..
    Mais comme approche, je trouve ça un peu brutal...
    Ma question, maintenant d'ordre général est:
    Qand je définis un pointeur vers une structure, et que je veux manipuler le pointeur comme un tableau dynamique, le compteur des éléments du tableau doit il être dans la structure? et dans ce cas, comment initialiser, si je veux éviter ce genre de problème (le genre que je viens d'obtenir quand je modifie le premier élément du tableau dynanmique)..
    D'avance merci..

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    je ne sais pas si j'ai bien compris ta problèmatique, mais il me semble que :

    Tu as une collection d'éléments du type in, que tu places dans un tableau alloué dynamiquement. Tu dois conserver le nombre d'éléments du tableau.
    La donnée à stocker est constituée des quantités groupées dans la structure in.
    Par contre, le nombre d'éléments de la collection n'a rien à voir avec les données, il est lié à la collection et il faut définir un type pour représenter la collection : un simple pointeur sur les données ne suffit pas.

    On peut alors envisager de structurer le programme de la façon suivante (j'ai changé les identificateurs que je trouve peu explicite):

    Les données et les fonctions associées:
    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
    // Une donnée
    typedef struct
    {
       //.....
       int identifiant;
    }Data;
    // Les fonctions associées aux données:
    void AfficheData(Data p)
    {
      //....
      printf("%d\n",p.identifiant);
     
    }
    Data InitialiseData(int iden)
    {
      Data inst;
      // ....  
      inst.identifiant = iden;
      return inst;
    }
    //.... etc
    La collection de données et les fonctions de manipulation de la collection
    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
    // Une collection
    typedef struct
    {
       Data * data;
       int nbdata;
    } Collection;
    //Les fonctions de manipulation de la collection : 
    // Création, destruction, affichage, ajout  et modification d'un élément, ...  
    // Création d'une collection
    Collection * CreerCollection(void)
    {
      Collection *coll = malloc( sizeof *coll);
      if(coll != NULL)
      {
        coll->data = NULL;
        coll->nbdata = 0;
      }
      return coll;
    }
    // Destruction d'une collection
    void DetruireCollection( Collection *coll)
    {
      if(coll!= NULL)
      {
        free(coll->data);
        free(coll);
      }
    }
    // Affichage de la collection
    void AfficheCollection(Collection *coll)
    {
       int i;
       if (coll != NULL)
          for(i=0; i<coll->nbdata;i++) AfficheData(coll->data[i]);
    }
    // Ajout d'un élément à la collection
    // Renvoie une valeur != NULL en cas d'insertion réussie
    // et NULL si insertion impossible
    void* AjouterCollection( Collection * coll, Data data)
    {
      Data * p = realloc(coll->data, (coll->nbdata + 1)*sizeof(Data));
      if(p != NULL)
      {
         coll->data = p;
         p[coll->nbdata] = data;
         coll->nbdata ++;
       }
       return p;
    }
    // .... etc.
    Le main() prend par exemple l'allure :
    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
    int main(void)
    {
      Collection* p = CreerCollection();
      Data ins1 = InitialiseData(1);
      Data ins2 = InitialiseData(2);
      Data ins3 = InitialiseData(3);
      Data ins4 = InitialiseData(4);
     
      // si on veut tester la réussite :  
      if(AjouterCollection(p,ins1)==NULL)printf("\n ajout d'une nouvelle donnee impossible \n");
      // sinon simplement
      AjouterCollection(p,ins2);
      AjouterCollection(p,ins3);
      AjouterCollection(p,ins4);
     
      AfficheCollection(p);
      DetruireCollection(p);
      return 0;
    }

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    251
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 251
    Par défaut
    Merci diogene.
    J'aime ta façon de répondre.
    C'est très professionnel.

    Je marque le sujet comme résol.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/03/2014, 09h56
  2. Réponses: 2
    Dernier message: 08/09/2011, 09h07
  3. Probleme pointeur sur une liste
    Par ba1boun2 dans le forum Débuter
    Réponses: 3
    Dernier message: 07/01/2009, 20h04
  4. [Débutant][jsp] évènement sur une liste
    Par phoebe dans le forum Servlets/JSP
    Réponses: 5
    Dernier message: 14/05/2004, 10h53
  5. [MFC] Problème pointeur sur une classe
    Par mick74 dans le forum MFC
    Réponses: 7
    Dernier message: 14/04/2004, 14h17

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