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

  FORUM HardWare.fr
  Programmation
  C

  Problème de gestion de liste chainée

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Problème de gestion de liste chainée

n°1347738
LorDjidane
GT & PSN ID : Lordji
Posté le 16-04-2006 à 17:45:24  profilanswer
 

Bonjour à tous.
 
Je dois réaliser un programme qui simule la gestion de mémoire d'un ordinateur, via liste chaînée.
Avec ce que j'ai fait, j'ai pu créer un processus. Mais dès que j'en crée un, il m'est impossible d'en créer un autre sans avoir de plantage au milieu. De plus, quand je veux afficher ma liste, j'ai un plantage lorsque j'ai créé un processus, sinon ça va (mais bon, sans processus, ça me fait un bloc à afficher, pas trop utile).
 
Je soupçonne mes pointeurs de se ballader un peu comme ils veulent, malheureusement, j'ai beau refaire le cheminement de mon programme sur une feuille de papier, je ne comprends pas ce qui se passe. De fait, une aide serait la bienvenue svp.
 
Voici le code (sans toutes les fonctions, uniquement celles utilisées) :  
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. typedef struct {
  5.   int numero, debut, taille;
  6.   char *tache;
  7.   char *utilisateur; } ELEMENT;
  8. typedef struct chainon {
  9.   ELEMENT val;
  10.   struct chainon *suiv; } CHAINON, *LISTE;
  11. LISTE creer(void)
  12. {
  13.   char utilisateur[]="---";
  14.   char tache[]="---";
  15.   LISTE init = malloc(sizeof(init));
  16.   if (init) init->suiv = NULL;
  17.   else printf("Erreur ! Memoire insuffisante !" );
  18.   init->val.debut=0;
  19.   init->val.utilisateur = malloc(strlen(utilisateur));
  20.   init->val.tache = malloc(strlen(tache));
  21.   strcpy(init->val.utilisateur,utilisateur);
  22.   strcpy(init->val.tache,tache);
  23.   return init;
  24. }
  25. int listevide(LISTE l){
  26.   if (l->suiv == NULL) return(1);
  27.   else return(0);
  28. }
  29. LISTE ajouter(LISTE l, ELEMENT e){
  30.   LISTE p;
  31.   p=l;
  32.   while (((e.taille) > (p->val.taille)) && ((p->val.numero) != 0))
  33.     p=p->suiv;                                         
  34.   if (p == NULL)
  35.   {
  36.     printf("Taille de tache trop grande ou pas de bloc libre disponible.\n" );
  37.     return(l);
  38.   }
  39.  
  40.   else
  41.   {
  42.     if ((e.taille) == (p->val.taille))
  43.     { /* Taille du bloc = taille du processus a ajouter */
  44.       p->val.numero=e.numero;
  45.       p->val.tache=malloc(sizeof(e.tache));
  46.       p->val.utilisateur=malloc(sizeof(e.utilisateur));
  47.       strcpy(p->val.tache,e.tache);
  48.       strcpy(p->val.utilisateur,e.utilisateur);
  49.       return(l);
  50.     }
  51.     else {
  52.       /* Taille du bloc > taille du processus a ajouter */
  53.       /* Creation de bloc supplementaire */
  54.       LISTE g;
  55.       g = malloc(sizeof(CHAINON));
  56.       g->suiv=p->suiv;
  57.       g->val.numero=0;
  58.       g->val.taille=((p->val.taille)-(e.taille));
  59.       g->val.debut=((p->val.debut)+(e.taille));
  60.       p->suiv=g;
  61.       p->val.numero=e.numero;
  62.       p->val.taille=e.taille;
  63.       p->val.tache=malloc(sizeof(e.tache));
  64.       p->val.utilisateur=malloc(sizeof(e.utilisateur));
  65.       strcpy(p->val.tache,e.tache);
  66.       strcpy(p->val.utilisateur,e.utilisateur);
  67.       return(l);
  68.     }
  69.   }
  70. }
  71. LISTE rechercheou(LISTE l, ELEMENT e){
  72.   LISTE p;
  73.   p=l;
  74.   /* d'abord les tests numeriques */
  75.   printf("p->val.numero = %d\n",p->val.numero);
  76.   printf("e.numero = %d",e.numero);
  77.   if (listevide(l) == 1) {return(p); printf("\nArret 1bis ok\n" ); }
  78.   else while ((p->val.numero != e.numero) || (p->val.debut != e.debut) || (p->val.taille != e.taille) || (strcmp(p->val.tache,e.tache) != 0) || (strcmp(p->val.utilisateur,e.utilisateur) != 0 ))
  79.   {
  80.     p=p->suiv;
  81.     printf("\nArret 2bis ok\n" );
  82.   }
  83.   printf("\nArret 3bis ok\n" );
  84.   return(p); /* On retourne p, qui indiquera soit l'element trouve, soit NULL si pas de resultat */
  85. }
  86. void affiche(LISTE l){
  87.   printf("Bloc Numero : %d\n",l->val.numero);
  88.   printf("Taille      : %d\n",l->val.taille);
  89.   printf("Debut       : %d\n",l->val.debut);
  90.   printf("Utilisateur : %s\n",l->val.utilisateur);
  91.   printf("Tache       : %s\n",l->val.tache);
  92.   printf("------------------\n" );
  93. }
  94. void afficheliste(LISTE l){
  95.   LISTE p;
  96.   p=l;
  97.   while (p != NULL){
  98.     affiche(p);
  99.     p=p->suiv;
  100.   }
  101. }
  102. /* Après définition de ces fonctions de gestion de listes chainées, on va coder les fonctions de gestion de la mémoire */
  103. LISTE bloclibre(LISTE mem,int taille){
  104.   LISTE p;
  105.   int ok=0;
  106.   ELEMENT e;
  107.   e.numero=0;
  108.   e.taille=mem->val.taille;
  109.   printf("\nArret 1 ok\n" );
  110.   while (ok != 1){
  111.     p=rechercheou(mem,e);
  112.     printf("\nArret 2 ok\n" );
  113.     if (listevide(p) == 1){
  114.       return(p);
  115.       ok=1;
  116.     }
  117.   printf("\nArret 3 ok\n" );
  118.     if (p->val.taille >= taille){
  119.       p=p->suiv;
  120.   printf("\nArret 4 ok\n" );
  121.       bloclibre(p,taille);
  122.     }
  123.     else {
  124.       ok=1;
  125.       printf("\nArret 5 ok\n" );
  126.       return(p);
  127.     }
  128.   }
  129. }
  130. ELEMENT allouebloc(int taille, int numero, int debut, char *u, char *t){
  131.   ELEMENT e;
  132.   e.taille=taille;
  133.   e.numero=numero;
  134.   e.debut=debut;
  135.   e.utilisateur = malloc(strlen(u));
  136.   e.tache = malloc(strlen(t));
  137.   strcpy(e.utilisateur,u);
  138.   strcpy(e.tache,t);
  139.   return(e);
  140. }
  141. LISTE nouvelletache(LISTE mem, int taille, int numero, int debut, char *u, char *t){
  142.   ELEMENT e;
  143.   e=allouebloc(taille,numero,debut,u,t);
  144.   ajouter(mem,e);
  145. }
  146. int numeroprocess(int k){
  147.   return(k+1);
  148. }
  149. int main(void){
  150.   LISTE L,p;
  151.   int k=0;
  152.   int action,taille,num;
  153.   char utilisateur[20];
  154.   char tache[20];
  155.   L=creer();
  156.   L->val.taille=512; /* taille de ma liste */
  157.   printf("Bienvenue dans l'interpreteur de commande\n" );
  158.   printf("Tapez 5 pour l'aide\n" );
  159.   while(fin != 1){
  160.     printf("Que voulez-vous faire?\n" );
  161.     scanf("%d",&action);
  162.       if (action == 1){
  163. printf("Fonction Ajouter\n" );
  164. printf("Utilisateur  " );
  165. scanf("%s",utilisateur);
  166. printf("\nTache:   " );
  167. scanf("%s",tache);
  168. printf("\nTaille:    " );
  169. scanf("%d",&taille);
  170. p=bloclibre(L,taille);
  171. printf("\n Valeurs pour le bloc libre p : debut %d taille %d\n",p->val.debut,p->val.taille);
  172. printf("\nTache de %s intitulee %s de taille %d\n",utilisateur,tache,taille);
  173. nouvelletache(L,taille,numeroprocess(k),p->val.debut,utilisateur,tache);
  174. k++;
  175.       }
  176.       if(action == 3){
  177. printf("Fonction Affichage\n" );
  178. afficheliste(L);
  179.       }
  180.     }
  181.   }
  182. return 0;
  183. }


 
(les printf("Arret" ); me servent à savoir, avec les tests ci-dessous, à quel niveau mon programme plante)
 
Quelques tests :  
 
Je ne crée rien et affiche directement la liste, aucun problème :  

Citation :


Fonction Affichage
Bloc Numero : 0
Taille      : 512
Debut       : 0
Utilisateur : ---
Tache       : ---
------------------


Je crée un processus uniquement, aucun problème :  

Citation :


Fonction Ajouter
Utilisateur  lordji
 
Tache:   gaim
 
Taille:    50
 
Arret 1 ok
p->val.numero = 0
e.numero = 0
Arret 2 ok
 
 Valeurs pour le bloc libre p : debut 0 taille 512
 
Tache de lordji intitulee gaim de taille 50


J'en crée un autre tout de suite après, j'ai droit à un freeze à la fin de ce qui s'affiche en dernier, le programme a l'air de boucler un peu, puis ma console (sous win) plante ("ce programme va se terminer (...)" ) :

Citation :


Fonction Ajouter
Utilisateur  lordji
 
Tache:   gcc
 
Taille:    120
 
Arret 1 ok
p->val.numero = 1
e.numero = 0
Arret 2bis ok
 
Arret 2bis ok


Quand, après avoir créé un seul processus, je demande l'affichage de ma liste, j'ai de même que ci-dessus, un freeze (avec tournage en rond avant) ; ce qui me surprend, c'est qu'il n'affiche pas les deux dernières chaînes de caractère :

Citation :


Fonction Affichage
Bloc Numero : 1
Taille      : 50
Debut       : 0
Utilisateur : lordji
Tache       : gcc
------------------
Bloc Numero : 0
Taille      : 462
Debut       : 50


 
Voilà, c'est un peu long, désolé, mais c'est pour clarifier au maximum la chose.
D'avance merci.

mood
Publicité
Posté le 16-04-2006 à 17:45:24  profilanswer
 

n°1347763
Emmanuel D​elahaye
C is a sharp tool
Posté le 16-04-2006 à 19:29:31  profilanswer
 

LorDjidane a écrit :


Voici le code (sans toutes les fonctions, uniquement celles utilisées) :  


Ne compile pas


Compiling: main.c
main.c: In function `main_':
main.c:178: error: `fin' undeclared (first use in this function)
main.c: At top level:
main.c:201: error: syntax error before "return"
main.c: In function `allouebloc':
main.c:144: warning: function returns an aggregate
main.c: In function `nouvelletache':
main.c:158: warning: function call has aggregate value


  • Ajouté int fin = 0;
  • Supprimé } en trop dans main()
  • Il est extrèmement confusant de cacher les pointeurs. Je supprimme donc le type LISTE.
  • De plus il nomme un pointeur sur un noeud, ce qui est encore plus confusant. Le type 'liste 'est plutôt une structure comprenant le pointeur de tête et le pointeur de fin de la liste... Je me réserve la possibilité de rebâtir un type 'liste' pour simplifier le codage ...
  • bloclibre() : Inutile de mettre du code après un return, il ne sera pas exécuté...
  • bloclibre() : algo tordu. Eviter les return au mileu des boucles. Utiliser break, les flags, un return unique...
  • allouebloc() : structure locale etrange. Une allocation, c'est dynamique. Là, il y a un mélange de copie et d'allocation... Pas clair et très douteux...
  • nouvelletache() ne retourne rien malgré son prototype...
  • bref, c'est un peu n'importe quoi tout ça...

Je te conseille de commencer par travailler sur les listes chainées sans trop de préoccuper des données (un simple 'int' de contrôle suffit). Ensuite, tu compliques en mettant des données plus complexes. une structre allouée dynamiquement, par exemple...


Message édité par Emmanuel Delahaye le 16-04-2006 à 19:55:38

---------------
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/

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

  Problème de gestion de liste chainée

 

Sujets relatifs
Problème avec fwrite() : besoin d'un coup de mainProbleme dans FormHandler : FCKeditor ne veut pas de textes longs
Problème largeur de baliseprobleme de connexion a une base de donnée sur no-sec..
Problème de ciblage avec adsenseproblème d'affichage sous firefox et safari
firefox ne bascule pas en UTF-8, probleme d'en-tête.[C TCP/IP] Gestion d'erreur sur un send
[VBA][Excel] Help ! Problème avec graphiqueTorque : problème de socket réutilisée
Plus de sujets relatifs à : Problème de gestion de liste chainée


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