C++ problème pointeur
Résolu/Fermé
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
-
5 janv. 2009 à 11:49
mrh Messages postés 51 Date d'inscription lundi 21 janvier 2008 Statut Membre Dernière intervention 3 mars 2009 - 7 janv. 2009 à 16:06
mrh Messages postés 51 Date d'inscription lundi 21 janvier 2008 Statut Membre Dernière intervention 3 mars 2009 - 7 janv. 2009 à 16:06
A voir également:
- C++ problème pointeur
- Pointeur souris disparu windows 10 - Guide
- Pointeur souris - Guide
- Pointeur souris disparu pc portable asus - Guide
- Cercle bleu pointeur souris clignote en permanence windows 10 ✓ - Forum Windows 10
- Pointeur souris instable - Forum souris / Touchpad
14 réponses
MRAD
Messages postés
86
Date d'inscription
mardi 21 octobre 2008
Statut
Membre
Dernière intervention
17 avril 2009
4
5 janv. 2009 à 12:58
5 janv. 2009 à 12:58
Bonjour,
Le code semble bien ecrit, et ce n'est question d'allocation memoire ici, p est un parametre parvenue du main donc il sera declarer dans le main, est ce que je pe avoir le code de ton main ?
Le code semble bien ecrit, et ce n'est question d'allocation memoire ici, p est un parametre parvenue du main donc il sera declarer dans le main, est ce que je pe avoir le code de ton main ?
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
7 janv. 2009 à 12:14
7 janv. 2009 à 12:14
Oui, logique, j'ai juste corrigé ce que tu avais écrit. Il faut aussi descendre dans les raternités
Feuille* rechercher(string prenom,Feuille * p) { cout << p->Prenom << "av boucle" << endl; getch(); Feuille*tmp=p,*tmp1; while(p!=NULL ){ cout << p->Prenom << "dans boucle" << endl; getch(); if(p->Prenom==prenom) return p; if(tmp1=rechercher(prenom,p->TeteDescendance)!=0)return tmp1; p=p->FrereSoeurSuivant; } /* p=tmp; if(p->TeteDescendance!=NULL){ return rechercher(prenom,p->TeteDescendance); } else*/ return NULL; };Je pense que là tu devrais parcourir tout l'arbre.
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
7 janv. 2009 à 16:06
7 janv. 2009 à 16:06
J'ai enlevé les lignes inutiles et ajouté un petit commentaire et des parenthèses dans le test de relance :
Maintenant cela fonctionne pour tout l'arbre! Merci beaucoup d'avoir passé du temps sur mon problème!
Feuille* rechercher(string prenom,Feuille * p) { Feuille*tmp; while(p!=NULL ){ if(p->Prenom==prenom) return p; //Relance la recherche sur les descendants de p renvoi p si p->prenom==prenom if((tmp=rechercher(prenom,p->TeteDescendance))!=NULL)return tmp; p=p->FrereSoeurSuivant; } return NULL; };
Maintenant cela fonctionne pour tout l'arbre! Merci beaucoup d'avoir passé du temps sur mon problème!
Utilisateur anonyme
5 janv. 2009 à 12:37
5 janv. 2009 à 12:37
c est tou bete, il n y a pas d allocation mémoire ...
il te faut un
p = new Feuille(p);
en debut de fonction
il te faut un
p = new Feuille(p);
en debut de fonction
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
5 janv. 2009 à 12:54
5 janv. 2009 à 12:54
Salut.
Là je ne voi pas d'où peut provenir l'erreur.
As tu bien fermé tout tes arbres avec un NULL ?
Attention aussi aux arbres à double sens (precedent suivant) le traitement est un peu plus compliqué est peu causer des erreurs.
Dans ces cas là, il faut voir l'historique complet de l'exécution de ton programme et savoir exactement où il plante.
Si, petite erreur d'algo : après avoir chercher dans les descandants, tu met p à frere_soeur_suivant, même si la recherche s'est bien dérouler.
Par contre, si la recherche s'est mal dérouler, p devient NULL et tu essai d'accéder à FrereSoeurSuivant, ce qui peux provoqué une erreur. Il faut voir la taille d'un string, mais ça pourrait expliqué le 0x00038
si p vaut zéro, alors &(p->FrereSoeurSuivant) vaut : sizeof(prenom)+sizeof(nom)+sizeof(Date_nais)+sizeof(Feuille*)
38 en hexa donne 56 en décimal, si le pointeur est sur 8 octet (64 bit), il reste donc 48/3=16 octet pour chaque string
Là je ne voi pas d'où peut provenir l'erreur.
As tu bien fermé tout tes arbres avec un NULL ?
Attention aussi aux arbres à double sens (precedent suivant) le traitement est un peu plus compliqué est peu causer des erreurs.
Dans ces cas là, il faut voir l'historique complet de l'exécution de ton programme et savoir exactement où il plante.
Si, petite erreur d'algo : après avoir chercher dans les descandants, tu met p à frere_soeur_suivant, même si la recherche s'est bien dérouler.
Par contre, si la recherche s'est mal dérouler, p devient NULL et tu essai d'accéder à FrereSoeurSuivant, ce qui peux provoqué une erreur. Il faut voir la taille d'un string, mais ça pourrait expliqué le 0x00038
si p vaut zéro, alors &(p->FrereSoeurSuivant) vaut : sizeof(prenom)+sizeof(nom)+sizeof(Date_nais)+sizeof(Feuille*)
38 en hexa donne 56 en décimal, si le pointeur est sur 8 octet (64 bit), il reste donc 48/3=16 octet pour chaque string
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
5 janv. 2009 à 14:25
5 janv. 2009 à 14:25
Merci pour vos réponses,
Le Main étant assez conséquent je n'écrirais que la partie concerné.
p est déclaré de cette manière dans main :
Feuille * p=NULL;
la fonction rechercher est lancé de cette manière
recherche("Firmin",p=tete);
tete est la tête de la liste chaînée.
"Firmin" est saisie par l'utilisateur.
L'arbre commence par "Leon" qui n'a pas de frère ou soeur et qui a "Firmin" comme 1ér enfant
Quand je lance la fonction ecrit au dessus la trace est la suivante :
Leon av boucle
Leon dans boucle
Firmin av boucle
Firmin ap boucle
PLANTAGE DU PROGRAMME :
0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000038.
Quand je lance la fonction avec "Leon" comme prénom elle fonctionne car elle ne passe pas tant que.
J'ai fait un test en modifiant le statut de Firmin je le fait devenir le frere de Leon plutôt que son fils dans ce cas là la fonction marche aussi.
Le problème est à partir du moment que je rappelle la fonction rechercher le programme plantera.
Merci de votre aide.
Le Main étant assez conséquent je n'écrirais que la partie concerné.
p est déclaré de cette manière dans main :
Feuille * p=NULL;
la fonction rechercher est lancé de cette manière
recherche("Firmin",p=tete);
tete est la tête de la liste chaînée.
"Firmin" est saisie par l'utilisateur.
L'arbre commence par "Leon" qui n'a pas de frère ou soeur et qui a "Firmin" comme 1ér enfant
Quand je lance la fonction ecrit au dessus la trace est la suivante :
Leon av boucle
Leon dans boucle
Firmin av boucle
Firmin ap boucle
PLANTAGE DU PROGRAMME :
0xC0000005: Violation d'accès lors de la lecture de l'emplacement 0x00000038.
Quand je lance la fonction avec "Leon" comme prénom elle fonctionne car elle ne passe pas tant que.
J'ai fait un test en modifiant le statut de Firmin je le fait devenir le frere de Leon plutôt que son fils dans ce cas là la fonction marche aussi.
Le problème est à partir du moment que je rappelle la fonction rechercher le programme plantera.
Merci de votre aide.
Utilisateur anonyme
5 janv. 2009 à 14:26
5 janv. 2009 à 14:26
tu n as donc pas alloué de mémoire à p dans le main
aprés Feuille * p=NULL; écrit
p = new Feuille(p);
ca devrait peut etre marcher
aprés Feuille * p=NULL; écrit
p = new Feuille(p);
ca devrait peut etre marcher
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
5 janv. 2009 à 14:42
5 janv. 2009 à 14:42
non ça ne peut pas marcher il faut allouer de la mémoire seulement quand on veut insérér des nouvelles données.
Or la je veut juste me positionner sur l'adresse mémoire qui contient p->prenom == "Firmin".
Je lance la fonction avec comme argument recherche("Firmin",p=tete) .
p vaut tete donc pourquoi je mettrais ensuite dans la fonction p = new Feuillle;
Or la je veut juste me positionner sur l'adresse mémoire qui contient p->prenom == "Firmin".
Je lance la fonction avec comme argument recherche("Firmin",p=tete) .
p vaut tete donc pourquoi je mettrais ensuite dans la fonction p = new Feuillle;
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
>
Utilisateur anonyme
5 janv. 2009 à 15:00
5 janv. 2009 à 15:00
laisse tombé, le problème ne viens pas de là, sinon le programme planterai des la première ligne, alors que là on voi clairement que le premier affichage est cohérent.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
5 janv. 2009 à 14:58
5 janv. 2009 à 14:58
Comme je t'ai dit, ça viens de l'algo.
Attention à la subtilité de ton code !
tu fait un appel récurent à recherche ! donc en partant de leon, il descend et relance la fonction recherche("firmin",Leon->TeteDescendance); Là il trouve car Firmin est directement un fils de leon, donc il marque "Firmin ap boucle" et sort de la seconde fonction rechercher pour revenir dans la première, la tu met p à Firmin->freresuivant et tu demande son prénom. Si firmin n'as pas de frere c'est normal que ça plante !
ta logique est mauvaise, à retravailler.
Attention à la subtilité de ton code !
tu fait un appel récurent à recherche ! donc en partant de leon, il descend et relance la fonction recherche("firmin",Leon->TeteDescendance); Là il trouve car Firmin est directement un fils de leon, donc il marque "Firmin ap boucle" et sort de la seconde fonction rechercher pour revenir dans la première, la tu met p à Firmin->freresuivant et tu demande son prénom. Si firmin n'as pas de frere c'est normal que ça plante !
Feuille* rechercher(string prenom,Feuille * p)// p pointe une premire fois sur Leon puis sur Firmin { cout << p->Prenom << "av boucle" << endl; getch(); while(p!=NULL && p->Prenom!=prenom){ cout << p->Prenom << "dans boucle" << endl; getch(); if(p->TeteDescendance!=NULL){ rechercher(prenom,p->TeteDescendance);// là tu passe Firmin à rechercher() } p=p->FrereSoeurSuivant;// si p vaut Leon, p pointe maintenant vers son frère, c'est là qu'est l'erreur } cout << p->Prenom << "ap boucle" << endl; getch(); if(p->Prenom==prenom){ return p; } else{ return NULL; } };
ta logique est mauvaise, à retravailler.
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
5 janv. 2009 à 15:03
5 janv. 2009 à 15:03
Feuille * p=NULL;
p est un pointeur sur la structure Feuille initialisé à NULL
quand je lance la fonction recherche je fais
p=tete;
tete est le premier pointeur sur Feuille de ma liste chaînée
J'insiste on n'alloue pas plusieurs fois pour les même informations donc vu que p=tete je n'ai pas a mettre
p = new Feuille;
p est un pointeur sur la structure Feuille initialisé à NULL
quand je lance la fonction recherche je fais
p=tete;
tete est le premier pointeur sur Feuille de ma liste chaînée
J'insiste on n'alloue pas plusieurs fois pour les même informations donc vu que p=tete je n'ai pas a mettre
p = new Feuille;
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
5 janv. 2009 à 15:10
5 janv. 2009 à 15:10
Je voudrais que quand la fonction trouve Firmin elle fait return p où p=Firmin
Et que une fois que j'ai fait un return toute les fonctions rechercher lancé avant soit s'arrete soit renvoi p=Firmin
C'est possible, si oui comment faire?
Et que une fois que j'ai fait un return toute les fonctions rechercher lancé avant soit s'arrete soit renvoi p=Firmin
C'est possible, si oui comment faire?
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
5 janv. 2009 à 15:39
5 janv. 2009 à 15:39
Pour ça, il faut tester le retour de ta fonction rechercher. Deux solutions, une facile mais n'explorant pas tout :
Feuille* rechercher(string prenom,Feuille * p) { cout << p->Prenom << "av boucle" << endl; getch(); while(p!=NULL && p->Prenom!=prenom){ cout << p->Prenom << "dans boucle" << endl; getch(); if(p->TeteDescendance!=NULL){ return rechercher(prenom,p->TeteDescendance); } p=p->FrereSoeurSuivant; } cout << p->Prenom << "ap boucle" << endl; getch(); if(p->Prenom==prenom){ return p; } else{ return NULL; } };Une plus propre (enfin j'espère)
Feuille* rechercher(string prenom,Feuille * p) { cout << p->Prenom << "av boucle" << endl; getch(); while(p!=NULL ){ cout << p->Prenom << "dans boucle" << endl; getch(); if(p->Prenom==prenom) return p; p=p->FrereSoeurSuivant; } if(p->TeteDescendance!=NULL){ return rechercher(prenom,p->TeteDescendance); } else return NULL; };tu cherche d'abord dans les freres et soeur, et si tu n'y trouve rien, tu cherches dans les descendants. Et tu retourne NULL si il n'y en a pas.
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
5 janv. 2009 à 16:55
5 janv. 2009 à 16:55
Merci pour tes solutions, malheureusement elles ne fonctionnent pas pour tout l'arbre.
Je voulais me servir de la récursivité pour diminuer et clarifier le code mais j'ai l'impression que ce sera pas pour tout de suite
Voici la fonction Rechercher sans récursivité que j'ai écrite et qui fonctionne pour tous les cas, c'est une usine à gaz mais sa marche si tu trouve plus simple merci de me prévenir
Feuille* rechercher(string prenom,Feuille * p)
{
Feuille * tete_liste = NULL;
Feuille * suite_liste = NULL;
Feuille * liste_descendant=NULL;
//la boucle cherche la personne avec le prenom donné
while(p->Prenom!=prenom && p!=NULL){
//gére le cas où un des enfants de la liste du descendant actuel à des descendants
if (p->FrereSoeurSuivant!=NULL && p->TeteDescendance!=NULL){
if(tete_liste==NULL){
tete_liste = p->TeteDescendance;
liste_descendant = tete_liste;
}
else{
if (suite_liste==NULL){
suite_liste=p->TeteDescendance;
tete_liste->TeteDescendance=suite_liste;
}
else{
suite_liste->TeteDescendance=p->TeteDescendance;
suite_liste=suite_liste->TeteDescendance;
}
}
}
//Si p a un frere on passe à son frere
if(p->FrereSoeurSuivant!=NULL){
p = p->FrereSoeurSuivant;
}
//Si p n'a pas de frere
else{
//Si p a un descendant
if(p->TeteDescendance!=NULL){
p = p->TeteDescendance;
}
//Si p n'a pas de descendant
else{
//Si il y existe un descendant pour un frere ou descendant precedent
if(tete_liste!=NULL){
p = tete_liste;
tete_liste = tete_liste->TeteDescendance;
}
else{
p = NULL;
}
}
}
}
if(p->Prenom==prenom){
return p;
}
else{
return NULL;
}
};
PS:pour Nagashiwa il n'y a pas d'allocation de mémoire dans ma fonction et elle marche parfaitement.
Je voulais me servir de la récursivité pour diminuer et clarifier le code mais j'ai l'impression que ce sera pas pour tout de suite
Voici la fonction Rechercher sans récursivité que j'ai écrite et qui fonctionne pour tous les cas, c'est une usine à gaz mais sa marche si tu trouve plus simple merci de me prévenir
Feuille* rechercher(string prenom,Feuille * p)
{
Feuille * tete_liste = NULL;
Feuille * suite_liste = NULL;
Feuille * liste_descendant=NULL;
//la boucle cherche la personne avec le prenom donné
while(p->Prenom!=prenom && p!=NULL){
//gére le cas où un des enfants de la liste du descendant actuel à des descendants
if (p->FrereSoeurSuivant!=NULL && p->TeteDescendance!=NULL){
if(tete_liste==NULL){
tete_liste = p->TeteDescendance;
liste_descendant = tete_liste;
}
else{
if (suite_liste==NULL){
suite_liste=p->TeteDescendance;
tete_liste->TeteDescendance=suite_liste;
}
else{
suite_liste->TeteDescendance=p->TeteDescendance;
suite_liste=suite_liste->TeteDescendance;
}
}
}
//Si p a un frere on passe à son frere
if(p->FrereSoeurSuivant!=NULL){
p = p->FrereSoeurSuivant;
}
//Si p n'a pas de frere
else{
//Si p a un descendant
if(p->TeteDescendance!=NULL){
p = p->TeteDescendance;
}
//Si p n'a pas de descendant
else{
//Si il y existe un descendant pour un frere ou descendant precedent
if(tete_liste!=NULL){
p = tete_liste;
tete_liste = tete_liste->TeteDescendance;
}
else{
p = NULL;
}
}
}
}
if(p->Prenom==prenom){
return p;
}
else{
return NULL;
}
};
PS:pour Nagashiwa il n'y a pas d'allocation de mémoire dans ma fonction et elle marche parfaitement.
Char Snipeur
Messages postés
9813
Date d'inscription
vendredi 23 avril 2004
Statut
Contributeur
Dernière intervention
3 octobre 2023
1 298
5 janv. 2009 à 18:01
5 janv. 2009 à 18:01
Normal, ereur de ma part. essai
Feuille* rechercher(string prenom,Feuille * p) { cout << p->Prenom << "av boucle" << endl; getch(); Feuille*tmp=p; while(p!=NULL ){ cout << p->Prenom << "dans boucle" << endl; getch(); if(p->Prenom==prenom) return p; p=p->FrereSoeurSuivant; } p=tmp; if(p->TeteDescendance!=NULL){ return rechercher(prenom,p->TeteDescendance); } else return NULL; };
mrh
Messages postés
51
Date d'inscription
lundi 21 janvier 2008
Statut
Membre
Dernière intervention
3 mars 2009
7 janv. 2009 à 11:53
7 janv. 2009 à 11:53
Merci pour ta réponse.
La fonction que tu ma donné ne marche pas pour le cas suivant :
on a 3 frères
2 d'entre eux on des enfants
Le parcours des enfants ne se fait que sur le 1er frère le 3 ème n'est pas parcouru
impossible de trouver un enfant du 3ème frère avec ta fonction.
Donc c'est presque ça il manque un petit truc et ce sera bon.
La fonction que tu ma donné ne marche pas pour le cas suivant :
on a 3 frères
2 d'entre eux on des enfants
Le parcours des enfants ne se fait que sur le 1er frère le 3 ème n'est pas parcouru
impossible de trouver un enfant du 3ème frère avec ta fonction.
Donc c'est presque ça il manque un petit truc et ce sera bon.