Liste CHaine, un big probleme!!

Liste CHaine, un big probleme!! - C - Programmation

Marsh Posté le 23-11-2007 à 22:54:36    

Voila, j'ai une fonction qui ne marche pas dans ma liste chainée, c'est lorsque je veux supprimer un element de la liste. il y une erreur, voila le code source :

 


Code :
  1. int Supprimer(*noeud debutListe, int x) {
  2. *noeud unNoeud=debutListe;
  3. *noeud temp;
  4. if(!Rechercher(unNoeud,x)) return 0; // si L'element n'existe pas dans la liste, je retourne 0
  5.  while(unNoeud->n!=x){
  6.   unNoeud=unNoeud->suivant;
  7. }
  8. temp=unNoeud;
  9. unNoeud=unNoeud->suivant;
  10. free(temp);
  11. return 1; // SUprression réussi
  12. }
 

Voila après avoir vérifié que le noeud existe dans la liste, je le cherche. et je l'affecte à un pointeur temporaire, puis j'accroche l'element suivant et je fais un "free" de l'element a supprimer.

 

Mais j'ai ce message d'erreur : "Heap corruption detected : after normal block...CRT detected that the application wrote to memory after end of heap buffer...

 

Voila aidez moi comment faire pour supprimer un element de la liste.

Message cité 1 fois
Message édité par harlem le 24-11-2007 à 14:02:50

---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 23-11-2007 à 22:54:36   

Reply

Marsh Posté le 24-11-2007 à 00:20:41    

harlem a écrit :

Voila, j'ai une fonction qui ne marche pas dans ma liste chainée, c'est lorsque je veux supprimer un element de la liste. il y une erreur, voila le code source :  
 
 

Code :
  1. int Supprimer(*noeud debutListe, int x) {
  2. *noeud unNoeud=debutListe;
  3. *noeud temp;
  4. if(!Rechercher(l,x)) return 0; // si L'element n'existe pas dans la liste, je retourne 0
  5. ...




Tu ne recherches pas x dans debutListe x?
 

Reply

Marsh Posté le 24-11-2007 à 01:10:34    

je parcours toute la liste jusqu'a que je trouve l'entier x, en faite. et debutListe c'est le pointeur sur le debut de la liste.

Message cité 1 fois
Message édité par harlem le 24-11-2007 à 01:10:59

---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 24-11-2007 à 11:04:32    

harlem a écrit :

je parcours toute la liste jusqu'a que je trouve l'entier x, en faite. et debutListe c'est le pointeur sur le debut de la liste.


Oui sauf que tu recherche dans l au lieu de debutliste!

Reply

Marsh Posté le 24-11-2007 à 11:58:40    

1) A quoi ça sert de chercher si l'élément existe ? A rien, et ça te fait parcourir deux fois ta liste chainée si l'élément existe.
 
2) Tu free() le bon élément, mais par contre tu n'enlève pas le bon élément de ta liste (tu enlèves l'élément suivant l'élément que tu es sensé supprimer). Je suppose que c'est ce qui provoque l'erreur : au prochain accès, tu va accéder à de la mémoire libérée.

Reply

Marsh Posté le 24-11-2007 à 14:06:04    

breizhbugs a écrit :


Oui sauf que tu recherche dans l au lieu de debutliste!


 
Non ça c'etait une faute de frappe, c'est pas le probleme  :)


---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 24-11-2007 à 14:10:30    

matafan a écrit :

1) A quoi ça sert de chercher si l'élément existe ? A rien, et ça te fait parcourir deux fois ta liste chainée si l'élément existe.
 
2) Tu free() le bon élément, mais par contre tu n'enlève pas le bon élément de ta liste (tu enlèves l'élément suivant l'élément que tu es sensé supprimer). Je suppose que c'est ce qui provoque l'erreur : au prochain accès, tu va accéder à de la mémoire libérée.


 
Meme si c'etais le cas, je ne vois pas pourquoi ça refuserait le "free", vu que le probleme est au niveau du free.
 
 
DOnc t'aurais fais comment?


---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 24-11-2007 à 14:46:10    

Voila tout le code source, vous pouvez tester, toujours le probleme avec la fonction supprimer :
 
 

Code :
  1. // ListeChaines.cpp : définit le point d'entrée pour l'application console.
  2. //
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. typedef struct noeud noeud;
  6. typedef struct noeud{
  7. int n;
  8. noeud * suivant;
  9. }*liste; //equivaut à noeud *
  10. //Recherche dans liste si le noeud pour lequel noeud->n=x, renvoi 1 si oui sinon 0
  11. int Rechercher(liste l, int x) {
  12. liste unNoeud;
  13. unNoeud=l;
  14. while(unNoeud!=NULL){
  15.  if(unNoeud->n==x) return 1; // si on trouve le noeud
  16.  unNoeud=unNoeud->suivant;
  17. }
  18. return 0;//on renvoie 0 si le noeud n'a pas été trouvé
  19. }
  20. int Inserer(liste * l, int x) { //pointeur de pointeur
  21. liste noeudCourant;
  22. liste nouveau;
  23. if(*l!=NULL) {
  24.  noeudCourant=*l;
  25.  while(noeudCourant->suivant!=NULL) { //=> tant qu'on est pas à la fin de la chaine
  26.   noeudCourant=noeudCourant->suivant;
  27.  }
  28.  nouveau=(liste) malloc(sizeof(liste));
  29.  if(!nouveau)exit(1); //On arrete le programme si l'alocation à échoué
  30.  //insertion à la suite
  31.  nouveau->n=x;
  32.  nouveau->suivant=NULL;
  33.  noeudCourant->suivant=nouveau;
  34.  return 1;
  35. }else{
  36.  //création du premier element
  37.  nouveau=(liste) malloc(sizeof(liste));
  38.  nouveau->n=x;
  39.  nouveau->suivant=NULL;
  40.  *l=nouveau;
  41.  return 2;
  42. }
  43. }
  44. int Supprimer(liste l, int x) {
  45. liste unNoeud=l;
  46. liste temp;
  47. liste precedent=l;
  48. if(!Rechercher(l,x)) return 0; // L'element n'existe pas dans la chaine
  49.  while(unNoeud->n!=x){
  50.   unNoeud=unNoeud->suivant;
  51. }
  52. temp=unNoeud;
  53. unNoeud=unNoeud->suivant;
  54. free(temp);
  55. return 1; // SUprression réussi
  56. }
  57. void AfficheListe(liste l) {
  58. int nb=0;
  59. liste unNoeud=l;
  60. while(unNoeud!=NULL) {
  61.  nb++;
  62.  printf("\n Noeud numéro %d : %d", nb, unNoeud->n);
  63.  unNoeud=unNoeud->suivant;
  64. }
  65. printf("\nLa liste comporte %d element(noeud)\n", nb);
  66. }
  67. //DEBUT DU PROGRAMME;
  68. liste maListe=NULL;
  69. int rep, valeur, retour;
  70. void main(){
  71. do{
  72.  printf("\n 1 - INSERTION \n" );
  73.  printf("\n 2 - RECHERCHER \n" );
  74.  printf("\n 3 - SUPPRIMER \n" );
  75.  printf("\n 4 - AFFICHER LA LISTE \n" );
  76.  printf("\n 0 - QUITTER \n" );
  77.  printf("Entrez le chiffre \n" );
  78.  scanf("%d", &rep);
  79.  switch(rep) {
  80.   case 1 :
  81.    //Insertion
  82.    printf("Entrez l'entier pour enregistrer \n" );
  83.    scanf("%d", &valeur);
  84.    retour=Inserer(&maListe, valeur);
  85.    if(retour==1) {
  86.     printf("Insertion réussi \n" );
  87.    }else if (retour==2){
  88.     printf("Nouvel liste \n" );
  89.     }else{
  90.     printf("Echec de l'insertion \n" );
  91.    break;
  92.   case 2 :
  93.    //recherche
  94.    printf("Entrez l'entier pour rechercher \n" );
  95.    scanf("%d", &valeur);
  96.    retour=Rechercher(maListe, valeur);
  97.    if(retour) {
  98.     printf("Le noeud existe dans la liste chainée \n" );
  99.    }else{
  100.     printf("Le noeud ne se trouve pas dans la chaine\n" );
  101.    }
  102.    break;
  103.   case 3 :
  104.    //Suppression
  105.    printf("Entrez l'entier pour suppresion\n" );
  106.    scanf("%d", &valeur);
  107.    retour=Supprimer(maListe, valeur);
  108.    if(retour) {
  109.     printf("Le noeud à été supprimé de la liste \n" );
  110.    }else{
  111.     printf("Ce noeud n'existe pas" );
  112.    }
  113.    break;
  114.   case 4 :
  115.    //Affichage de la liste
  116.    AfficheListe(maListe);
  117.    break;
  118.  }
  119.  }
  120. }while(rep!=0);
  121. }


---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 24-11-2007 à 16:53:21    

harlem a écrit :


 
Meme si c'etais le cas, je ne vois pas pourquoi ça refuserait le "free", vu que le probleme est au niveau du free.
 
 
DOnc t'aurais fais comment?


En fait j'ai lu un peu vite, en fait tu n'enlève pas du tout le noeud de la liste... Mais tu le free() quand même. Pourqoui ça plante sur le free ? Je ne sais pas, tu ne donnes aucun détail sur la suite d'opérations qui conduit au problème. Comme tu n'enlève pas les éléments de la liste, j'imagine que tu finis pas faire un free() sur un élément déja supprimé.
 
Note aussi que si tu passe un noeud * à Supprimer, tu ne pourra jamais supprimer le premier élément.
 
Je ferais un truc comme ça (pas testé, mais tu vois l'idée) :

Code :
  1. int Supprimer(liste *l_addr, int x) {
  2.         noeud *n;  /* Sera le noeud à supprimer quand on l'aura trouvé */
  3.         noeud **s; /* Addresse où écrire pour supprimer l'élément */
  4.         /* Si on veut supprimer le premer élément, c'est la tête de liste
  5.          * qu'il faudra modifier.
  6.          */
  7.         s = l_addr;
  8.         /* Recherche l'élément à supprimer */
  9.         for (n = *l_addr; /* rien */; n = n->suivant) {
  10.                 if (!n) return 0;     /* Fin de liste */
  11.                 if (n->n == x) break; /* Element trouve */
  12.                 /* Dorénavant c'est l'élement précédent qu'il faudra modifier */
  13.                 s = &(n->suivant);
  14.         }
  15.         /* On "ponte" l'élément à supprimer */
  16.         *s = n->suivant;
  17.         /* Puis on le libère */
  18.         free(n);
  19.        
  20.         return 1;
  21. }


Message édité par matafan le 24-11-2007 à 17:10:02
Reply

Marsh Posté le 24-11-2007 à 17:50:17    

c'est bon ça marche, en faite c'etai un probleme avec ce visual studio de m...., j'ai mis le code source sur dev++ et ça marche sans probleme. Et effectivement je n'enlever pas le noeud de la liste, j'ai tout corrigé, Merci


---------------
fallout 3 NEUF : http://forum.hardware.fr/forum2.ph [...] w=0&nojs=0
Reply

Marsh Posté le 24-11-2007 à 17:50:17   

Reply

Marsh Posté le 24-11-2007 à 18:39:13    

Je doute que le problème vienne de Visual Studio.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed