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

  FORUM HardWare.fr
  Programmation
  C

  [C] [urgent] supprimer la derniere cellule d une file ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] [urgent] supprimer la derniere cellule d une file ?

n°1389989
XTinX
Amicalement votre
Posté le 18-06-2006 à 15:21:51  profilanswer
 

Salut a tous, je suis trop en galere pke mon projet bloque a cause d un probleme bizarre. Voyez plutot :
 
void construire_arbre_recouvrement(T_File_message file){
     
    T_File_message courant=file;
    while(courant->suivant){
        courant=courant->suivant;
    }    
    T_Routeur * pere=courant->pere;
    T_Routeur * routeur=courant->fils;
    T_Cle cle= courant->cle;
    printf("courant: %x\n",courant);
    printf("file: %x\n",file);    
    free(courant);
    courant=NULL;
    printf("apres liberation courant: %x\n",courant);
    printf("apres liberation file: %x\n",file);    
    assert(courant == NULL);  
 
 
 
 
c est la partie du code qui foire. Qd le programme passe pr la premiere fois dans cette fonction la file contient 1 message et devrait donc, par l intermediare du pointeur courant, se retrouver a NULL apres la libération (puisque dans ce cas courant = file). Bref, a l execution ca m affiche:
 
 
courant: 2ad48
file: 2ad48
apres liberation courant: 0
apres liberation file: 2ad48
 
 
Donc en fait le free ne marche pas du tout !!!!!!! Qq1 pourrait m aider ?


Message édité par XTinX le 18-06-2006 à 20:48:25
mood
Publicité
Posté le 18-06-2006 à 15:21:51  profilanswer
 

n°1389992
Je@nb
Kindly give dime
Posté le 18-06-2006 à 15:41:26  profilanswer
 

file pointe toujours sur l'adresse 2ad48 mais cette adresse ne contient plus rien vu que tu l'as libérée via le free de courant

n°1390010
XTinX
Amicalement votre
Posté le 18-06-2006 à 16:22:17  profilanswer
 

Je@nb a écrit :

file pointe toujours sur l'adresse 2ad48 mais cette adresse ne contient plus rien vu que tu l'as libérée via le free de courant


 
file vaut 2ad48, c'est la valeur du pointeur ! C est pour ca que je comprends pas.

n°1390015
Je@nb
Kindly give dime
Posté le 18-06-2006 à 16:43:14  profilanswer
 

Code :
  1. T_File_message courant=file; //je suppose que courant est un pointeur et file aussi
  2. printf("courant: %x\n",courant); // j'affiche l'adresse pointée par courant
  3. printf("file: %x\n",file); // j'affiche l'adresse pointée par file
  4. free(courant); // je libère la structure qui est pointée par courant, donc je libère xx octets à l'adresse qui débute à *courant
  5. courant=NULL; // je fais pointer courant maintenant à NULL
  6. printf("apres liberation courant: %x\n",courant); // j'affiche l'adresse pointée par courant
  7. printf("apres liberation file: %x\n",file); // j'affiche l'adresse pointée par file


Vu que tu n'a pas modifiée file c'est normale que sa valeus (aka l'adresse qu'il pointe) soit la même adresse que avant.
Maintenant si tu fais un printf("file pointe sur : %x",*file); tu va te prendre un segfault vu que l'adresse pointée par file a été libérée

n°1390100
XTinX
Amicalement votre
Posté le 18-06-2006 à 18:28:03  profilanswer
 

Comment faut faire alors pour parcourir la file jusqu a la derniere cellule, l'utiliser et la liberer (et donc mettre le champ "suivant" de la cellule precedante à NULL) ????

n°1390106
XTinX
Amicalement votre
Posté le 18-06-2006 à 18:43:13  profilanswer
 

Help please, j en suis la :
 
 
void construire_arbre_recouvrement(T_File_message * file){
     
    T_File_message initiale=*file;  
    T_File_message * courant=file;
    while((*courant)->suivant){
 printf("while\n" );    
        *courant=(*courant)->suivant;
    }    
    T_Routeur * pere=(*courant)->pere;
    T_Routeur * routeur=(*courant)->fils;
    T_Cle cle= (*courant)->cle;
    free((*courant));
    (*courant)=NULL;
    assert(*courant == NULL);
    *file=initiale;
 
 
mais ca ne marche tjrs pas, comme il y a un appel recursif plus loins ds la fonction, je boucle dans le while


Message édité par XTinX le 18-06-2006 à 18:44:16
n°1390110
Sve@r
Posté le 18-06-2006 à 18:50:45  profilanswer
 

XTinX a écrit :

Comment faut faire alors pour parcourir la file jusqu a la derniere cellule, l'utiliser et la liberer (et donc mettre le champ "suivant" de la cellule precedante à NULL) ????


Hum... ta question dénote un petit défaut de conception.
Il te faut distinguer "utilisation" et "libération" sinon cela risque de te mener à de gros pb.
 
Sinon, pour libérer le dernier élément, il sufit de balayer toute la file en mémorisant à chaque fois l'élément précédent

void freeLast(T_file *cellule)
{
      T_file *courant;
      T_file *prev;
 
       // Si la file est vide => Arrêt fonction (inutile si t'es certain que ça n'arrive jamais)
       if (courant == NULL)
           return;
       
      // Balayage de toute la file
      for (courant=cellule, prev=NULL; courant->suivant != NULL; courant=courant->suivant)
           prev=courant;
 
      // On libère le courant (qui se trouve sur le dernier élément)
      free(courant);
 
      // Si le précédent n'est pas nul (donc s'il y a au-moins deux éléments)
      if (prev)
      {
           // On positionne son suivant à NULL
           prev->suivant=NULL;
      }
}


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1390115
XTinX
Amicalement votre
Posté le 18-06-2006 à 18:58:16  profilanswer
 

Le probleme c est que je l utilise et une fois que c est fait je la libère !
 
je vais essayer avec ta fonction merci !

n°1390120
XTinX
Amicalement votre
Posté le 18-06-2006 à 19:04:04  profilanswer
 

Bon et bien ca ne marche tjrs pas.
 
Y a aussi un detail :
 
T_File_message est de type pointeur sur T_Message (qui est le type de chaque cellule)

n°1390121
XTinX
Amicalement votre
Posté le 18-06-2006 à 19:06:10  profilanswer
 

Voial le code en entier:
 
 
void construire_arbre_recouvrement(T_File_message * file){
     
    T_File_message  courant=*file;
    while(courant->suivant){
 printf("while\n" );    
        courant=courant->suivant;
    }  
    T_Routeur * pere=courant->pere;
    T_Routeur * routeur=courant->fils;
    T_Cle cle= courant->cle;
    freeLast(*file);
    printf("taille file : %d\n",taille_file(*file));  
    if(indice_cle_presente(*routeur,cle)== -1){    
 T_Table * table = creer_table_routage(pere,cle);
 table_add(&routeur->tables,table);
 if(pere){
     T_Table * table_paternelle;
     table_paternelle=table_routage(*pere,cle);
     routeur_add(&table_paternelle->fils,routeur);
 }
 for(int i=0;i<(routeur->voisins).nb;i++){
     ajouter_dans_file(file,routeur,routeur->voisins.elements[i],cle);
 }
    }
     
    if(*file){
 construire_arbre_recouvrement(file);
    }
}

mood
Publicité
Posté le 18-06-2006 à 19:06:10  profilanswer
 

n°1390122
XTinX
Amicalement votre
Posté le 18-06-2006 à 19:08:28  profilanswer
 

et son petit frere :
 
 
 
 
void ajouter_dans_file(T_File_message *file,T_Routeur * pere,T_Routeur * fils,T_Cle cle){
 
    T_File_message ptr_message;
 
 
    ptr_message=malloc(sizeof(T_Message));
    ptr_message->pere=pere;
    ptr_message->fils=fils;
    ptr_message->cle=cle;
    ptr_message->suivant=*file;
    *file=ptr_message;
}

n°1390125
XTinX
Amicalement votre
Posté le 18-06-2006 à 19:21:11  profilanswer
 

Cette fonction ajoute un element en debut de file
 
C est peut etre celle la qui foire ??

n°1390134
XTinX
Amicalement votre
Posté le 18-06-2006 à 19:35:20  profilanswer
 

Ca marche tjrs pas  :cry:  :cry:  :cry:  :cry:  :cry:

n°1390149
XTinX
Amicalement votre
Posté le 18-06-2006 à 20:40:33  profilanswer
 
n°1390162
GrosBocdel
Posté le 18-06-2006 à 21:24:26  profilanswer
 


Comment as-tu déclaré T_File_message? et T_routeur et T_cle
Parce que là tu es en train de jouer à placer des & et de * de façon complètement aléatoire. Cela dit c'est vrai qu'au pif tu as une chance non nulle pour que ça finisse par fonctionner.

Message cité 1 fois
Message édité par GrosBocdel le 18-06-2006 à 21:27:26
n°1390169
Sve@r
Posté le 18-06-2006 à 21:56:30  profilanswer
 

XTinX a écrit :

void construire_arbre_recouvrement(T_File_message * file){
     
    T_File_message  courant=*file;
    while(courant->suivant){
 printf("while\n" );    
...
}



Horreur !!! Tu déclares un élément nommé "courant" de type "T_file_message" et tu lui passes en copie "*file" (la copie de structures, même si ça peut se faire avec précautions, c'est LONG !!!)
Mais dans la ligne du dessous, tu l'utilises avec l'opérateur "->" comme si c'était un pointeur !!!
Je crois que tu te mélanges sacrément les pinceaux avec les pointeurs, les structures, les pointeurs de structures et tout le reste...
 
Je vais essayer de te résumer le principe de manipulations des listes
1) tu déclares une structure te permettant de manipuler un élément de ta liste. Cette structure contient les données plus un pointeur contenant l'adresse de l'élément suivant. Du style

typedef struct s_noeud {
    data
    data
    data
    struct s_noeud *suivant;
} t_noeud;


 
2) tu déclares une structure te permettant de manipuler ta liste complète. En fait, cette structure contient l'adresse du premier élément de ta liste. Avec ce premier élément tu peux aller au suivant, puis au suivant etc.
La structure peut contenir d'autres objets utiles, comme un pointeur sur le dernier, un pointeur sur l'élement en cours de traitement, etc. C'est totalement facultatif mais aussi totalement évolutif et modulable. Style

typedef struct {
    t_noeud *premier;
    t_noeud *dernier;
    t_noeud *courant;
} t_liste;


Si un élément t'intéresse pas, tu le mets pas. Si t'as besoin d'autres éléments, tu les rajoutes.
 
Ensuite, dans ton "main()", tu déclares juste un "t_liste liste" et tu remplis chaque element à "NULL". Avec cette simple variable (qui peut être vue comme "poignée" de ta liste), tu tiens ta liste entière. Lorsque tu veux passer ta liste à une fonction quelconque, tu lui passes "&liste" et la fonction reçoit un pointeur sur "t_liste" style "t_liste *liste". Avec ce pointeur, ta fonction a accès au premier élément (avec "liste->premier" ) puis du premier elle peut passer au suivant etc etc et traiter toute la liste.
 
Dernier conseil: bien souvent, un dessin aide à la compréhension...
 

GrosBocdel a écrit :

Cela dit c'est vrai qu'au pif tu as une chance non nulle pour que ça finisse par fonctionner.


Cette hypothèse a déjà été évoquée. Si tu places un singe devant une machine à écrire durant un temps infini, tu obtiendras à un moment ou un autre l'ensemble complet des oeuvres de Shakespeare... :D  


Message édité par Sve@r le 18-06-2006 à 22:00:56

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
n°1390227
Je@nb
Kindly give dime
Posté le 19-06-2006 à 00:03:28  profilanswer
 

Soit tu le fais en itératif avec un pointeur qui pointe sur un élément de ta file et que tu déplace, soit tu y va en récursif.
 
genre :
 

Code :
  1. typedef struct telem {
  2.   int val;
  3.   struct telem *suivant;
  4. } elem;
  5. typedef file *elem;
  6. file mafile;
  7. //Remplissage de mafile
  8. file delLast(file uneliste) {
  9.   if (uneliste == NULL) { // Si la file est nulle
  10.      return NULL;
  11.   }
  12.   if (uneliste->suivant == NULL) {
  13.     free(uneliste);
  14.     return NULL;
  15.   }
  16.   uneliste->suivant = delLast(uneliste->suivant);
  17.   return uneliste;
  18. }

n°1390248
XTinX
Amicalement votre
Posté le 19-06-2006 à 09:20:17  profilanswer
 

En fait j ai trouvé la solution, il faut faire 2 cas:
 
le cas ou tu supprimes le premier éléments de la liste (si jamais il n y a que ca ds la liste)  
 
et le cas ou tu supprimes le dernier element.
 
 
 
La premiere fois tu utilises un pointeur de pointeur vers la premiere cellule (pour pouvoir modifier le pointeur)
 
La deuxieme fois tu utilises un pointeur simple pour parcourir la file
 
 
 
Voila ! et merci qd meme a tous

n°1391860
Sve@r
Posté le 20-06-2006 à 23:49:01  profilanswer
 

Je@nb a écrit :

Soit tu le fais en itératif avec un pointeur qui pointe sur un élément de ta file et que tu déplace, soit tu y va en récursif.


Le récursif est à éviter chaque fois que c'est possible !!!


---------------
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] [urgent] supprimer la derniere cellule d une file ?

 

Sujets relatifs
[résolu]Probleme sous Visual Studio avec FILEBloquer le champ texte d'un input type file
[URGENT]Insérer des champs dans un texte/occurence d'un stylemodifier le contenu d'une cellule [résolu]
Utra urgent exam demain!!![VBA-Excel] [Resolu] Insérer et supprimer des feuilles
[Urgent : Serveur Ftp ][resolu] erreur C1083 Cannot open include file ...ça a l'air tout bête
Arrière plan de cellule de tableauURGENT probleme
Plus de sujets relatifs à : [C] [urgent] supprimer la derniere cellule d une file ?


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