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 :

Listes Chainées et libération mémoire?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Par défaut Listes Chainées et libération mémoire?
    Bonjour,

    Je travail sur un projet en C dans lequel j'utilise de longues listes chainées...

    Voici un exemple de liste :

    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
    struct data_POSS
    {
       int valide;
       int Tab1[50];
       int Tab2[200];
    };
     
    struct node_POSS
    {
       struct data_POSS data;
       struct node_POSS *psuiv;
       struct node_POSS *pprec;
    };
     
    struct liste_POSS
    {
       struct node_POSS *pTete;
       struct node_POSS *pQueue;
       int Nb_Elements;
    };
    Ensuite je l'instancie de la manière suivante :

    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
    void add_POSS (struct liste_POSS *p_liste, struct data_POSS *p_data)
    {
       struct node_POSS *pNouveau = malloc (sizeof *pNouveau);
       if (pNouveau != NULL)
       {
          pNouveau->data = *p_data;
          pNouveau->psuiv = NULL;
     
          if (p_liste->pTete == NULL)
          {
          /* Premier maillon = Premiere Ligne */
             p_liste->pTete = pNouveau;
             pNouveau->pprec = NULL;
          }
          else
          {
             p_liste->pQueue->psuiv = pNouveau;
             pNouveau->pprec = p_liste->pQueue;
          }
          p_liste->pQueue = pNouveau;
       }
    }
     
    void Create_liste (struct liste_POSS *p_POSS)
    {
      int i, j;
      struct data_POSS data_CP;
     
      p_POSS->Nb_Elements = 0;
     
      for (i=0;i<65534;i++)
        {
    	data_CP.valide=1;
    	for (j=0;j<50;j++) {data_CP.Tab1[j]=0;}
    	for (j=0;j<200;j++) {data_CP.Tab2[j]=0;}
     	add_POSS(p_POSS, &data_CP);
    	p_POSS->Nb_Elements = p_POSS->Nb_Elements + 1;
         }                                        
    }
    Dans mon Main.c j'appelle la fonction Create_liste afin de créer une chaine.
    Après, avoir travaillé sur cette chaine j'essaie de la réinitialiser en rappelant la fonction Create_liste...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Main ()
    {
         int i;
         struct liste_POSS TOTO_liste = {NULL, NULL, 0};
     
         for (i=0;i<5;i++) 
         {
              Create_liste(&TOTO_liste);
     
            // UTILISATION et TRAITEMENT DE LA LISTE
     
         }
    Or, la fonction Create_liste ne donne pas a chaque fois le même nombre d'éléments dans la liste chainée... au début j'ai bien 35535, puis ensuite ca diminue...
    Mon programme est assez gros, et utilise beaucoup de liste et liste de liste...
    Aussi, je me suis dit que c'etait peut etre un probleme mémoire et j'ai ajouté:

    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
    void liberation_Mem (struct liste_POSS *C_POSS)
    {
         struct node_POSS *p_sw = C_POSS->pTete;
         struct node_POSS *p_tmp;
     
         while (p_sw!=NULL)
         {
               p_tmp = p_sw->psuiv;
               free(p_sw);
               C_POSS->pTete = p_tmp;
     
               p_sw = C_POSS->pTete;
         }    
    }
     
    void Main ()
    {
         int i;
         struct liste_POSS TOTO_liste = {NULL, NULL, 0};
     
         for (i=0;i<5;i++) 
         {
              Create_liste(&TOTO_liste);
     
            // UTILISATION et TRAITEMENT DE LA LISTE
     
              liberation_Mem (&TOTO_liste );
     
         }
    Est ce que la libération de mémoire est correcte?

    Merci pour votre aide,

    Alex

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    D'ici, ça a l'air correct.

    Simplement, tu devrais peut-être remettre les pointeurs à NULL dans la structure, au cas où on tenterait d'y accéder après libération...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre expérimenté Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Par défaut
    Il y a quelque chose d'étrange dans votre fonction "add_POS", vous faites:

    struct node_POSS *pNouveau = malloc (sizeof *pNouveau);

    Alors qu'a priori pNouveau n'est pas un type mais un élément
    Vous vouliez faire j'imagine:

    struct node_POSS *pNouveau = malloc (sizeof ( struct node_POSS));

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    ^Non, c'est la manière correcte de faire.
    Ainsi, si le type de pNouveau est modifié, il y aura moins de remplacements à faire.

    La seule difficulté c'est de ne pas oublier l'étoile.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Par défaut
    Merci pour votre aide !

    Du coup, si c'est bon, je ne comprends pas pourquoi Create liste ne crée pas toujours 65534 cellules...

    Si je vérifie comme ça par exemple :

    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
    void Create_liste (struct liste_POSS *p_POSS)
    {
      int i, j, COmpteur;
      struct data_POSS data_CP;
     
      p_POSS->Nb_Elements = 0;
     
      for (i=0;i<65534;i++)
        {
    	data_CP.valide=1;
    	for (j=0;j<50;j++) {data_CP.Tab1[j]=0;}
    	for (j=0;j<200;j++) {data_CP.Tab2[j]=0;}
     	add_POSS(p_POSS, &data_CP);
    	p_POSS->Nb_Elements = p_POSS->Nb_Elements + 1;
         }      
     
         struct node_POSS *p_swp =  p_POSS->pTete;
         while (p_swp!=NULL)
         {
             COmpteur++;
             p_swp = p_swp->psuiv;
          }
         printf("%d\t%d\r\n", p_POSS->Nb_Elements, COmpteur);
     
    }
    On obtient toujours p_POSS->Nb_Elements = 65534 mais COmpteur peut avoir une autre valeur...

    Y a t il une solution pour voir combien de mémoire le programme utilise ???

    Car j'avais déjà des plantages "aléatoires" du programme que j'ai résolus en ajoutant la fonction "liberation_Mem"... Du coup, je me dis que ça doit encore être du à ça...

  6. #6
    Membre expérimenté Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Par défaut
    Je pense que le problème vient peut-être de votre fonction

    void add_POSS (struct liste_POSS *p_liste, struct data_POSS *p_data)
    En effet, vous y faites
    pNouveau->data = *p_data;
    Or *p_data contient deux tableaux, vous n'allez donc pas recopié les tableaux de cette façon , et pire encore une partie de la mémoire réservée par votre malloc ne sera plus accessible.

  7. #7
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Par défaut
    Je ne comprends pas pourquoi...

  8. #8
    Membre expérimenté Avatar de quetzacoatl
    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    168
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2011
    Messages : 168
    Par défaut
    Ecrire quelque chose du genre tab1=tab2 ne recopie pas tab2 dans tab1, les tableaux étant en réalité des pointeurs, on affecte au pointeur tab1 qui pointe sur la première case d'un tableau, l'adresse de la premiere case de tab2.
    Ainsi tab1 pointe sur la première case de tab2, mais il n'y a pas de recopie comme on désirait.
    Et je pense que l'espace mémoire réservé par tab1 n'étant plus pointée, cela peut peut-être causé des soucis.

    Pour recopier les tableaux il faut utilisr des fonctions du genre memcpy()

  9. #9
    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
    Dans Create_liste(), COmpteur n'est pas initialisé à 0 , d'où des résultats farfelus .

  10. #10
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Par défaut
    ça c'est une erreur de saisie... quand j'ai écrit le code sur le forum...
    Compteur est bien initialisé !

    Et au fur et a mesure des ré initialisation de la liste, le nombre d'éléments décroit...

    Je vais ajouter ça, ca me donnera surement plus d'info...

    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
     
    void add_POSS (struct liste_POSS *p_liste, struct data_POSS *p_data)
    {
       struct node_POSS *pNouveau = malloc (sizeof *pNouveau);
     
       if (pNouveau != NULL)
       {
          pNouveau->data = *p_data;
          pNouveau->psuiv = NULL;
     
          if (p_liste->pTete == NULL)
          {
          /* Premier maillon = Premiere Ligne */
             p_liste->pTete = pNouveau;
             pNouveau->pprec = NULL;
          }
          else
          {
             p_liste->pQueue->psuiv = pNouveau;
             pNouveau->pprec = p_liste->pQueue;
          }
          p_liste->pQueue = pNouveau;
       }
       else // l'allocation a échoué
      { 
        printf("C'est la que ca merde !\r\n");
      }
     
    }

  11. #11
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Citation Envoyé par alexglvr Voir le message
    ça c'est une erreur de saisie... quand j'ai écrit le code sur le forum...
    Pourquoi tu t'embêtes à retaper le code à la main ? Utilise le copié/collé, ça va te simplifier énormément la vie.

  12. #12
    Membre confirmé
    Inscrit en
    Octobre 2008
    Messages
    82
    Détails du profil
    Informations forums :
    Inscription : Octobre 2008
    Messages : 82
    Par défaut
    Pourquoi tu t'embêtes à retaper le code à la main ? Utilise le copié/collé, ça va te simplifier énormément la vie.
    Par ce que le code réel est beaucoup trop gros pour être posté, du coup, j'ai fait un petit code spécial qui montre mon problème ! Ça prend deux minutes, et ça simplifie la compréhension...

Discussions similaires

  1. Liste chainée en mémoire partagée
    Par drogeek dans le forum C
    Réponses: 2
    Dernier message: 21/05/2013, 07h13
  2. Liste chainé et fuite mémoire
    Par poussinphp dans le forum C++
    Réponses: 2
    Dernier message: 25/04/2007, 23h06
  3. mémoire et liste chainée?
    Par tintin72 dans le forum C++
    Réponses: 17
    Dernier message: 17/12/2005, 20h54
  4. Réponses: 24
    Dernier message: 30/10/2005, 09h27
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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