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 :

Pointeur dans fonction récursive


Sujet :

C

  1. #1
    Invité
    Invité(e)
    Par défaut Pointeur dans fonction récursive
    Bonjour.

    J'ai un problème avec mon programme, il plante tout le temps. Je vous ai mis le code ci-dessous. Le problème se situe dans la fonction "chainer" qui doit renvoyer une liste doublement chainée à la fonction main et à elle-même car il s'agit d'une fonction récursive. Quand le paramètre N vaut 1, la fonction ne s'appelle pas elle-même et il n'y a pas de problème. Par contre, quand N>1, le fonction "chainer" s'appelle elle-même et ça plante. Le débogage indique que le plantage a lieu à la ligne 85, c'est-à-dire quand la fonction s'appelle elle-même. En fait, la liste chainée "debinf" en question est un paramètre de la fonction, elle doit être unique, les modifications doivent se répercuter à chaque appel récursif de la fonction "chainé" et la liste chainée "debinf" doit être conservée pour construire les listes chainées suivantes à partir de la fonction main où se trouve une boucle qui se charge de cela, c'est pourquoi j'ai utilisé un pointeur pour "debinf" afin que sa valeur soit conservée lors de chaque itération dans le main.

    Pouvez-vous m'aider SVP? Merci d'avance.

    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
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
    #include<string.h>
    #include<math.h>
     
    const int N=2;
     
    typedef struct antichaine{
    	int tab[N];
    	struct antichaine *prec;
    	struct antichaine *suiv;
    }chaine;
     
    double fact(int n);
    //void liberation(chaine *parcours);
    chaine chainer(int n, int c, int val[], int *max, chaine *debinf);
    void affichage(chaine *ch, int n, int nb_ch);
     
     
    void main(){
    	int n=N;
    	int taille_esp=(int)pow((double)2,(double)n);
    	int m=(int)n/2;
    	int nb_ch=fact(n)/(fact(n-m)*fact(m)); //nombre de chaînes
    	n=N;
    	//int **esp=(int**)calloc(taille_esp,sizeof(int));	
    	int val[2]={0,1};
    	int i=0, j=0, k=0, c=n, max=2;
     
    	chaine *ch=(chaine*)calloc(nb_ch,sizeof(struct antichaine));
     
    	chaine *debinf=(chaine*)calloc(1,sizeof(struct antichaine));
    	debinf=NULL;
     
    	for(i=0;i<nb_ch;i++){
     
     
    		ch[i]=chainer(n,c,val,&max,debinf);
    		ch[i]=*ch[i].suiv;
    		ch[i].prec=NULL;
    		free(ch[i].prec);
    		affichage(&ch[i],n,nb_ch);
    		//printf("%d\n",debinf->tab[0]);
    	}
     
    }
     
    double fact(int n){
    	if(n<0){
          exit (EXIT_FAILURE);
    	}
    	else if(n==1 || n==0){
    		return 1;
    	}return n*fact(n-1);
    }
     
     
     
    void liberation(chaine *parcours){
    	while((parcours->suiv)!=NULL){
    		parcours=parcours->suiv;
    		free(parcours->prec->tab);
    	}
    	free(parcours->tab);
    	free(parcours);
    }
     
    chaine chainer (int n,int c, int val[], int *max, chaine *debinf){
    	int k,l;
    	//chaine *deb=(chaine*)malloc(sizeof(struct antichaine));
    	chaine *parcours=(chaine*)malloc(sizeof(struct antichaine));
    	//chaine *parcoursinf;
    	chaine *tmp;
    	chaine *suppr;
    	//deb->prec=NULL;
    	//deb->suiv=NULL;
    	//parcours=deb;
    	parcours->prec=NULL;
    	parcours->suiv=NULL;
     
    	if(debinf==NULL || (*max)<0){	
    		(*max)=2;
    		if(n>1){
    			debinf=chainer(n-1,c,val,max,debinf);
    		}
    		else if(n==1){
    			for(k=0;k<(*max);k++){
    				tmp=(chaine*)malloc(sizeof(struct antichaine));
    				tmp->prec=NULL;
    				tmp->suiv=NULL;
    				tmp->tab[n-1]=val[k];
    				parcours->suiv=tmp;
    				tmp->prec=parcours;
    				tmp->suiv=NULL;
    				parcours=parcours->suiv;
    			}
    			while(parcours->prec!=NULL){
    				parcours=parcours->prec;
    			}
    			return *parcours;
    		}
    		else if(n==0){
    			exit (EXIT_FAILURE);
    		}
    	}
    	if(debinf!=NULL){
    		//liberation(parcours);
    		chaine *parcours=(chaine*)malloc(sizeof(struct antichaine));
    		parcours->prec=NULL;
    		parcours->suiv=NULL;
    		//parcoursinf=debinf;
    		for(k=0;k<(*max);k++){
    			tmp=(chaine*)malloc(sizeof(struct antichaine));
    			tmp->prec=NULL;
    			tmp->suiv=NULL;
    			for(l=0;l<n-1;l++){
    				tmp->tab[l]=debinf->tab[l];
    			}
    			tmp->tab[n-1]=val[k];
    			parcours->suiv=tmp;
    			tmp->prec=parcours;
    			tmp->suiv=NULL;
    			parcours=parcours->suiv;
    		}
    		debinf=debinf->suiv;
     
    		while(debinf!=NULL){
    			tmp=(chaine*)malloc(sizeof(struct antichaine));
    			tmp->prec=NULL;
    			tmp->suiv=NULL;
    			for(l=0;l<n-1;l++){
    				tmp->tab[l]=debinf->tab[l];
    			}
    			tmp->tab[n-1]=val[(*max)];
    			parcours->suiv=tmp;
    			tmp->prec=parcours;
    			tmp->suiv=NULL;
    			parcours=parcours->suiv;
    			debinf=debinf->suiv;
    		}
    		while(debinf->prec!=NULL){
    			debinf=debinf->prec;
    		}
    		suppr=debinf;
    		debinf=debinf->suiv;
    		debinf->prec=NULL;
    		free(suppr);
     
    		(*max)=(*max)-1;
    	}
    	while(parcours->prec!=NULL){
    		parcours=parcours->prec;
    	}
    	//free(deb);
    	//free(parcours);
    	free(tmp);
    	return *parcours;
     
    }
     
    void affichage(chaine *ch, int n, int nb_ch){
    	int j;
     
    	while(ch!=NULL){
    		for(j=0;j<n;j++){
    			printf("%d",ch->tab[j]);
    		}
    		ch=ch->suiv;
    		printf(" ");
    	}
    	printf("\n");
     
    }

  2. #2
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Bon j'ai parcouru en diagonale ton code (vite fait quoi) mais j'ai noté deux choses :

    1. Quand tu alloues debinf, juste après tu fait :
      ce que je trouve pas logique du tout car tu perds ainsi le début de l'adresse de l'espace alloué, je vois pas pourquoi tu as fait ca
    2. Ta fonction chainer devrait pas plutôt retourner un pointeur de type chaine ? Je pose la question car dans la déclaration et définition de ta fonction tu as:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      chaine chainer(int n, int c, int val[], int *max, chaine *debinf);
      il manque alors le * soit
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      chaine * chainer(int n, int c, int val[], int *max, chaine *debinf);
    3. Le cast devant les *alloc n'est pas obligatoire en C sauf si tu veux compiler ton projet avec un compilateur C++ mais sinon cela alourdi inutilement ton code
    4. Tu devrais vérifier à chaque fois le retour des tes allocations, ca permet d'éviter des bugs et plantages facilement
    5. ...

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour tes conseils. Je vais essayer de les appliquer en espérant que ça marche. Je ne pourrai pas te répondre tout de suite pour te dire si ça a marché ou pas car je n'ai pas internet chez moi en ce moment et je suis obligé de venir au cyber, ce qui me ralentit considérablement.

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je vais en rajouter une couche:
    1/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		ch[i].prec=NULL;
    		free(ch[i].prec);
    Ca va être surprenant
    2/
    Dans chainer, en début de fonction du déclares
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chaine *parcours=(chaine*)malloc(sizeof(struct antichaine));
    .
    Tu refais la même déclaration ensuite dans le if(debinf!=NULL){. Pas très catholique ceci.
    3/ Ensuite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    			while(parcours->prec!=NULL){
    				parcours=parcours->prec;
    			}
    C'est s'embêter pour rien: déclare une variable chaine *L_pPremier = parcours dès le début.


    J'ai l'impression que tu t’emmêles un peu les pédales dans tes fonctions. Repose précisément ce que tu veux faire à chaque étape de ta fonction (ca s'appelle de la conception) et ensuite fait ton code. Une fois que tu auras les idées claires, cela devrait aller mieux.

Discussions similaires

  1. Calcul dans fonction récursive
    Par caroletexier dans le forum PL/SQL
    Réponses: 3
    Dernier message: 18/10/2011, 22h49
  2. Pointeur int dans fonction récursive
    Par Invité dans le forum Débuter
    Réponses: 5
    Dernier message: 29/05/2008, 16h38
  3. Réponses: 15
    Dernier message: 22/03/2007, 02h35
  4. Pointeur dans une fonction ?
    Par sliiim6184 dans le forum C
    Réponses: 4
    Dernier message: 28/12/2006, 11h32
  5. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 20h14

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