Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1411 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [c] liste simplement chainé==> pb [résolu==> merci]

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[c] liste simplement chainé==> pb [résolu==> merci]

n°1529761
castorgris
===>Miaou<===
Posté le 16-03-2007 à 22:37:27  profilanswer
 

Bonjour,
J'ai un problème avec ceci :

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. typedef struct liste
  4. {
  5. int x;
  6. struct liste* next;
  7. }liste;
  8. void ajouteFin(liste *l,int b) /* ajoute un element en fin de liste*/
  9. {
  10. liste *a;
  11. a=malloc(sizeof(liste));
  12. a->x=b;
  13. l->next=a;
  14.         a->next=NULL;
  15. }
  16. void ajouteDebut(liste *l,int b)/* ajoute element en début de liste*/
  17. {
  18. liste *a;
  19. a=malloc(sizeof(liste));
  20. a->x=b;
  21. a->next=l;
  22. l=a;/*pb */
  23. }
  24. int main()
  25. {
  26. liste *l=NULL;
  27. l=malloc(sizeof(liste));
  28. if(l!=NULL)
  29. {
  30.  l->x=1;
  31.  l->next=NULL;
  32.  ajouteDebut(l,4);
  33. }
  34. free(l);
  35. return 0;
  36. }


 
Il ne s'agit que de la manipulation de liste chainé.Le problème ce situe au niveau de l'ajout en début de liste.La procédure ne marche pas ( erreur de segmentation à l'execution) mais je ne comprend pas pourquoi.
Je pense avoir identifié le pb ( au niveau de l'affectation l=a), mais je ne comprend pas pourquoi ça foire.
 
Si quelqu'un avait la gentillesse de m'aider ....
 
 
Pour info, compilé avec gcc 4.1.2 sous ubuntu edgy eft.
Merci d'avance

Message cité 1 fois
Message édité par castorgris le 18-03-2007 à 18:21:50
mood
Publicité
Posté le 16-03-2007 à 22:37:27  profilanswer
 

n°1529762
Joel F
Real men use unique_ptr
Posté le 16-03-2007 à 22:42:33  profilanswer
 

pour modifier un pointeur, il est de bon aloi d'utiliser un pointeur de pointeur :o
 
Ta fonction ajouteDebut ne modifie en rien ta liste dans ton main

n°1529766
castorgris
===&gt;Miaou&lt;===
Posté le 16-03-2007 à 22:48:25  profilanswer
 

Un pointeur de pointeur ? c'est quoi cet animal ?  
Dois-je ecrire :
 
void ajouteDebut(liste **l,int b)
?

Message cité 1 fois
Message édité par castorgris le 16-03-2007 à 22:56:41
n°1529771
Trap D
Posté le 16-03-2007 à 23:08:00  profilanswer
 

Je te signale aussi que ta fonction ajouteFin ne fonctionne pas non plus. (en plus de ne pas initialiser a->next à NULL).
Il faut tester le retour des malloc et enfin, en C, on ne caste pas les malloc.

Message cité 1 fois
Message édité par Trap D le 16-03-2007 à 23:09:45
n°1529774
castorgris
===&gt;Miaou&lt;===
Posté le 16-03-2007 à 23:14:50  profilanswer
 

Trap D a écrit :

Je te signale aussi que ta fonction ajouteFin ne fonctionne pas non plus. (en plus de ne pas initialiser a->next à NULL).
 


Effectivement, mais c'est juste un couper coller malheureux

 
Trap D a écrit :


Il faut tester le retour des malloc


C'est à dire?

 


le castage ( heu... ça existe ?) des malloc vient aussi d'un oubli de modif du code pour repassage de c++ en c parcque pour une raison que j'ignore, un printf("%d", (l->next)->next) me donne une erreur de segmentation, mais pas un cout << (l->next)->x, sur les compilateur de mon ecole.


Message édité par castorgris le 16-03-2007 à 23:20:13
n°1529793
Trap D
Posté le 16-03-2007 à 23:54:01  profilanswer
 

Tu peux fort bien ne plus avoir de mémoire à ta disposition, aussi l'alllocation mémoire peut échouer et la fonction malloc te renvoie NULL. Donc, il faut tester le retour.

n°1529887
Emmanuel D​elahaye
C is a sharp tool
Posté le 17-03-2007 à 12:35:04  profilanswer
 

castorgris a écrit :

Un pointeur de pointeur ? c'est quoi cet animal ?  
Dois-je ecrire :
 
void ajouteDebut(liste **l,int b)
?


http://mapage.noos.fr/emdel/notes. [...] e_variable
 


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1530015
Sve@r
Posté le 17-03-2007 à 22:32:11  profilanswer
 

castorgris a écrit :

Bonjour,
J'ai un problème avec ceci :

Code :
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. typedef struct liste
  4. {
  5. int x;
  6. struct liste* next;
  7. }liste;
  8. void ajouteFin(liste *l,int b) /* ajoute un element en fin de liste*/
  9. {
  10. liste *a;
  11. a=malloc(sizeof(liste));
  12. a->x=b;
  13. l->next=a;
  14.         a->next=NULL;
  15. }
  16. void ajouteDebut(liste *l,int b)/* ajoute element en début de liste*/
  17. {
  18. liste *a;
  19. a=malloc(sizeof(liste));
  20. a->x=b;
  21. a->next=l;
  22. l=a;/*pb */
  23. }
  24. int main()
  25. {
  26. liste *l=NULL;
  27. l=malloc(sizeof(liste));
  28. if(l!=NULL)
  29. {
  30.  l->x=1;
  31.  l->next=NULL;
  32.  ajouteDebut(l,4);
  33. }
  34. free(l);
  35. return 0;
  36. }



Très gros problème de conception dans ce code
1) dans le main, tu fais "l=malloc()" => ok
2) ensuite, tu fais "ajouteDebut(l, 4) et dans la fonction "ajouteDebut", tu cherches à faire "a=malloc()" puis "l=a" => donc tu remplaces le résultat de ton malloc initial par le second malloc => t'as perdu ton pointeur initial !!!
Accessoirement, comme l'a dit Joel F, pour modifier une variable dans une fonction, il faut passer l'adresse de cette variable à la fonction qui la stocke dans un pointeur sur cette variable. Donc si tu veux modifier "l" qui est de type "liste *", tu dois passer "&l" à ta fonction qui la stockera dans un "liste **". Ensuite, dans ta fonction "ajouteDebut()", chaque fois que tu veux t'adresser à ton pointeur, tu dois utiliser "*l". Mais de toute façon, même si tu écris correctement ta fonction d'un point de vue syntaxique, tu planteras ton programme car tu perdras ton malloc initial.
 
Question: Pourquoi faire plein de malloc ? Pourquoi ne pas adopter un comportement "objet" qui serait "j'écris une fonction qui alloue de la mémoire et me remplis mon élément avec ma valeur et qui me renvoie l'adresse allouée" puis faire "j'appelle cette fonction quand j'ne ai besoin et j'insère l'élément alloué là où il faut"
 
Par exemple un truc de ce style

Code :
  1. liste* remplir(int val)
  2. {
  3.     liste* elem;
  4.     elem=malloc(sizeof(liste));
  5.     if (elem == NULL)
  6.       return NULL;
  7.     elem->x=val;
  8.     elem->next=NULL;
  9.     return elem;
  10. }
  11. void ajouteDebut(liste** maListe, liste* elem)
  12. {
  13.      if (*maListe == NULL)
  14.      {
  15.           *maListe=elem;
  16.           return;
  17.      }
  18.       elem->next=(*maListe);
  19.       *maListe=elem;
  20. }
  21. void ajouteFin(liste** maListe, liste* elem)
  22. {
  23.      liste *cur;
  24.      if (*maListe == NULL)
  25.      {
  26.           *maListe=elem;
  27.           return;
  28.      }
  29.      for (cur=(*maListe); cur->next != NULL; cur=cur->next);
  30.      cur->next=elem;
  31. }
  32. void videListe(liste* maListe)
  33. {
  34.     liste* cur;
  35.     if (maListe == NULL)
  36.        return;
  37.     for (cur=maListe->next; cur != NULL; cur=cur->next)
  38.     {
  39.          free(maListe);
  40.          maListe=cur;
  41.      }
  42. }
  43. int main()
  44. {
  45.       liste* l=NULL;
  46.       liste* elem;
  47.       elem=remplir(4);
  48.       if (elem != NULL)
  49.       {
  50.           ajouteDebut(&l, elem);
  51.           videListe(l);
  52.       }
  53.       return 0;
  54. }


 
C'est déjà un bon début. Ensuite, je ferais une différenciation entre "type élément" et "type liste" en créant des conteneurs spécialisés pour chacun. Ainsi, je pourrais manipuler plus facilement la liste en elle-même et/ou chaque élément qui la compose. Et je pourrais agrémenter la liste d'autres trucs utiles comme par exemple "nb d'éléments" ou "premier et dernier" ou autres outils...


Message édité par Sve@r le 17-03-2007 à 22:35:04

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1530146
castorgris
===&gt;Miaou&lt;===
Posté le 18-03-2007 à 18:21:09  profilanswer
 

Merci de passer du temps sur ça.
Ce petit bout de code est un exercie pour nous apprendre à manipuler des pointeurs.
Après moult tentative, j'en suis arrivé à  

Code :
  1. liste * ajouteDebut(liste* l, int valeur)
  2. {
  3.     liste* tmp = malloc(sizeof(liste));
  4.     tmp->x = valeur;
  5.     tmp->next = l;
  6.     return tmp;
  7. }


 
qui marche sans pb.Maiis j'ai changais d'approche par rapport à ce que j'avais ecrit au début.
Par contre je ne gère pas la liberation mémoire de tmp.
 
Merci pour ta solution sve@r, qui me semble bien plus "propre" et   moins maladroite .
 
Il faut que j'apprenne à utiliser l'approche objet du langage, parceque moi j'ai tendance à ecrire du code parfois fonctionnel ( souvent non ...) en barbare, surtout que l'usage que j'ai ( et que j'aurais)  est un usage "calcul".Je ne coderais jamais une application, mais des fonctions d'integration numérique si .
 
Merci pour l'aide.
je repasserais surement bientôt pour un autre problème ....

n°1530272
Joel F
Real men use unique_ptr
Posté le 18-03-2007 à 23:18:36  profilanswer
 

castorgris a écrit :


parceque moi j'ai tendance à ecrire du code parfois fonctionnel


 
Le mot que tu cherche, c'est pas plutôt "impérative" ;) ?
 
http://fr.wikipedia.org/wiki/Progr [...] ctionnelle
http://fr.wikipedia.org/wiki/Progr [...] 3%A9rative
 
:)

mood
Publicité
Posté le 18-03-2007 à 23:18:36  profilanswer
 

n°1530276
Emmanuel D​elahaye
C is a sharp tool
Posté le 18-03-2007 à 23:32:23  profilanswer
 

castorgris a écrit :

Il faut que j'apprenne à utiliser l'approche objet du langage


http://mapage.noos.fr/emdel/tad.htm


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1530290
castorgris
===&gt;Miaou&lt;===
Posté le 19-03-2007 à 07:24:21  profilanswer
 


 
Par fonctionnel je voulais dire "qui marche"...

n°1530291
castorgris
===&gt;Miaou&lt;===
Posté le 19-03-2007 à 07:24:54  profilanswer
 


 
 
Merci.Dès que j'ai un moment de libre j'irais voir.


Message édité par castorgris le 19-03-2007 à 07:25:11
n°1530610
Sve@r
Posté le 19-03-2007 à 16:17:30  profilanswer
 

castorgris a écrit :

Merci de passer du temps sur ça.
Ce petit bout de code est un exercie pour nous apprendre à manipuler des pointeurs.
Après moult tentative, j'en suis arrivé à  

Code :
  1. liste * ajouteDebut(liste* l, int valeur)
  2. {
  3.     liste* tmp = malloc(sizeof(liste));
  4.     tmp->x = valeur;
  5.     tmp->next = l;
  6.     return tmp;
  7. }


 
qui marche sans pb.


 
Ca marche sans problème à condition que, dans la fonction appelante, tu imposes que ta liste récupère ce que renvoie ta fonction "ajouteDebut" sinon ton début ne changera pas. C'est un défaut de conception car ta fonction qui est sensée ajouter un élément au début de la liste ne le fait en fait pas. C'est ta façon de récupérer ce qu'elle renvoie qui fera que ça marche ou pas...
 
Je vais te donner un début de code. Essaye de le comprendre pour le compléter ensuite avec les fonctions qui t'intéressent...

typedef struct elem {
    int x;
    struct elem *next;
} t_elem;
 
typedef struct {
    t_elem *debut;
} t_liste;
 
void listeInit(t_liste *liste)
{
    liste->debut=NULL;
}
 
int main()
{
    t_liste maListe;
    listeInit(&maListe);
 
    return 0;
}


Message édité par Sve@r le 19-03-2007 à 16:18:56

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [c] liste simplement chainé==> pb [résolu==> merci]

 

Sujets relatifs
[Résolu] Impossible d'installer PHP-MySQL sur mon microFaire un substring d'une chaine de caractères larges
[RESOLU] connection socket[Résolu] Gros problème de cache
[résolu] Variables dynamiques dans des classes[C++] STL - list : doit contenir uniquement des objets dynamiques ??
[javascript][résolu] charger une nouvelle page avec window.onloadVBA access execution de macro [résolu]
[Résolu] [Divers] crash d'un programme (Newsleecher)Liste de donnees
Plus de sujets relatifs à : [c] liste simplement chainé==> pb [résolu==> merci]


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR