IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Segfault dans un ABR


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 22
    Par défaut Segfault dans un ABR
    Salut à tous!
    Je suis en train de réaliser un programme visant à faire des opérations de bases dans un ABR (ajout d'une saisie de l'utilisateur dans l'arbre, suppression sur saisie de l'utilisateur...) et je me heurte à mon terrible ennemi le Segfault...) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    t_arbre* reserver(t_arbre * arbre, float currenttime, float arrivee) {            
             /*TESTS*/
             ...
             arbre=inserer_resa(arbre,arrivee);				//allocation et insertion de la nouvelle réservation
             printf("horaire valide :)!\n");
          }
     
          else {
             printf("horaire invalide!\n");
          }
       }
       else {
          printf("horaire invalide!\n");
       }
       return arbre; 
    }
     
     
     
    t_arbre *inserer_resa(t_arbre *arbre, float arrivee){ 		//inserer la réservation dans l'arbre
     
       if(arbre==NULL)
          return creer_noeud(arrivee);  				//si l'arbre est nul il suffit d'allouer et remplir le noeud
       else{
          if(arbre->aterrissage > arrivee)	{		
    /*si la valeur à ajouter est plus grande que le noeud courant, on fait une récursion sur le fils gauche, sinon, sur le fils droit*/
              arbre->g = inserer_resa(arbre->g, arrivee);
              return arbre;
          }
          else {
             arbre->d =  inserer_resa(arbre->d, arrivee);
      	 return arbre;
          }							 //le cas "égal" ne pose pas de problème puisqu'il ne peut pas se produire
       }
       return arbre;
    }
     
    /////////////////
     
    void suppress(t_arbre *arbre, float arrivee) {
       t_arbre *courant=arbre;
       t_arbre *pere=NULL;
       while ((courant!=NULL) && (arbre->aterrissage!= arrivee)){
          pere=courant;					//on cherche toujours à avoir l'identité du père du noeud courant
          if (arrivee<arbre->aterrissage)  			//si arrivee est plus petit, on cherche la valeur à supprimer dans le fils gauche
             courant=courant->g;  
          else 						//si arrivee>arbre->aterrissage, on cherche dans le sous arbre droit
             courant=courant->d;
       }							//on a donc normalement courant sur le noeud à supprimer
     
       if (courant==NULL){					//cependant peut etre que l'arrivee saisie ne correspondait à aucune réservation
          printf("erreur : l'heure saisie ne correspond à aucune réservation courante!\n");
          return;
       }
     
       if ((courant->d==NULL) && (courant->g==NULL)){		//si le noeud considéré est une feuille
             free(courant);
             return;
       }
     
       if ((courant->d==NULL)&&(courant->g!=NULL)) {		//s'il n'y a qu'un seul fils : le fils gauche
          if (pere->aterrissage>courant->aterrissage)		//si courant est le fils droit          
             pere->d=courant->g;
          else 							//si c'est le fils gauche
             pere->g=courant->g;
          free(courant);
          return;
       }
     
       if ((courant->g==NULL) && (courant->d!=NULL)) {
          if (pere->aterrissage>courant->aterrissage)
             pere->d=courant->d;
          else
             pere->g=courant->d;
          free(courant);
          return;      
       }
       if ((courant->g!=NULL) && (courant->d!=NULL)){			//si le noeud à supprimer a 2 fils
          float arr_pred=min(courant->g);				
    /*on stocke la valeur du plus petit prédécesseur du noeud considéré (à noter qu'on aurait aussi pu utiliser le "plus proche successeur" (le max du sous arbre droit)*/
          suppress(arbre,arr_pred);
          courant->aterrissage=arr_pred; 
       }
    }  
     
    int main() {
       t_arbre *arbre=malloc(sizeof(t_arbre));
       ...
       if (saisie==1){
          scanf(&arrivee);
          arbre=reserver(arbre,currenttime,arrivee);
       }
       if (saisie==2)
          suppress(arbre,arrivee);
      ...
    }
    Quand j'insère un élément, le programme segfault après m'avoir dit "horaire valide" ou "horaire invalide" et avant d'etre sorti de la fonction (le return ne lui plait pas?)...
    Quant à la fonction suppress, ça ne m'étonne pas qu'elle ne marche pas car elle est foireuse (enfin j'ai pas trop confiance) : pourriez-vous me dire qu'est ce qui ne va pas?
    (Vous allez sûrement dire que c'est scandaleux tellement c'est faux, mais bon, c'est comme ça qu'on progresse!)

    Merci

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 833
    Billets dans le blog
    1
    Par défaut
    Salut

    Ta fonction "inserer_resa()" se base sur le fait que le pointeur reçu est null or dans ton main, ton pointeur est alloué via malloc donc il ne peut pas être null. Mais ce qu'il contient est franchement hasardeux...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2014
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2014
    Messages : 22
    Par défaut
    En effet merci, ça marche!
    Apres moultes aventures toutes plus épiques les unes que les autres dans les méandres sombres et tortueux du débugage, mon programme a une dernière erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void clear(t_arbre * arbre, float currenttime){
       if (arbre!=NULL) {
          float tmp;
          while (min(arbre)<currenttime) {
             t_arbre *courant=arbre;
             while (courant->g!=NULL) {
                courant=courant->g;
                tmp=courant->aterrissage;
             }
             if (tmp<currenttime)
                suppress(&courant,tmp);
          }
       }
    }
    En gros je manipule des heures sous forme de float dans un ABR, cette fonction a pour but de supprimer toutes les heures inférieures à l'heure actuelle via l'appel de la fonction void suppress(t_arbre **root, float arrivee) qui elle est fonctionnelle : on récupère le min de l'arbre : s'il n'est pas inférieur au temps courant, il n'y a rien a faire, s'il l'est on appelle suppress sur le noeud contenant la valeur min et on recommence jusqu'à ce que le min ne soit plus inférieur au temps courant.
    Le problème, c'est que quand j'appelle la fonction, la 1ere fois il ne se passe rien (il y a pourtant bien une valeur expirée), la 2e fois (alors qu'il ne s'est rien passé la 1ere) segfault... et je ne vois pas pourquoi. Quelqu'un saurait m'aider dans cette ultime quête?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 9
    Dernier message: 28/12/2014, 13h48
  2. Segfault dans QAudioOutput
    Par boozook dans le forum Débuter
    Réponses: 2
    Dernier message: 06/06/2013, 13h06
  3. Segfault dans un code récalcitrant
    Par tixlegeek dans le forum C
    Réponses: 3
    Dernier message: 13/03/2010, 13h22
  4. [GDB] Segfault avant d'entrer dans le main()
    Par Kalith dans le forum Code::Blocks
    Réponses: 2
    Dernier message: 09/07/2008, 18h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo