supprimer la derniere cellule d une file ? [C] [urgent] - C - Programmation
Marsh Posté le 18-06-2006 à 15:41:26
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
Marsh Posté le 18-06-2006 à 16:22:17
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.
Marsh Posté le 18-06-2006 à 16:43:14
Code :
|
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
Marsh Posté le 18-06-2006 à 18:28:03
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) ????
Marsh Posté le 18-06-2006 à 18:43:13
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
Marsh Posté le 18-06-2006 à 18:50:45
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) |
Marsh Posté le 18-06-2006 à 18:58:16
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 !
Marsh Posté le 18-06-2006 à 19:04:04
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)
Marsh Posté le 18-06-2006 à 19:06:10
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);
}
}
Marsh Posté le 18-06-2006 à 19:08:28
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;
}
Marsh Posté le 18-06-2006 à 19:21:11
Cette fonction ajoute un element en debut de file
C est peut etre celle la qui foire ??
Marsh Posté le 18-06-2006 à 21:24:26
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.
Marsh Posté le 18-06-2006 à 21:56:30
XTinX a écrit :
|
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 { |
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 { |
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...
Marsh Posté le 19-06-2006 à 00:03:28
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 :
|
Marsh Posté le 19-06-2006 à 09:20:17
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
Marsh Posté le 20-06-2006 à 23:49:01
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 !!!
Marsh Posté le 18-06-2006 à 15:21:51
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