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 :

Récursivité et allocation dynamique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut Récursivité et allocation dynamique
    Bonjour à tous,

    Je rencontre actuellement un problème avec les libérations dans une de mes fonctions récursive, à t'on le droit d'allouer et liberer de cette manière:

    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
     
    void parcourir(parcours p, int nb_villes, int k,  bool * villeVisite){
     
      if(p->niveau == nb_villes){
        double dp=distanceParcours(p);
        for(int i=0; i<nb_villes; i++)
          printf("%d ",p->itineraire[i]);
        printf("%f \n",dp);
        if(dp < min->distance){
          min->distance = dp;
          copierItineraire(min->itineraire, p->itineraire, nb_villes);
        }
      }
     
      else{
        k_villes_pp tab = k_villesPlusProches( p->itineraire[p->niveau], villeVisite, k, nb_villes ); // allocation 1
        for(int i=0; i < k && i < tab->nb_vpp ; i++){
          bool * villeVisite_i = dupliquer(villeVisite, nb_villes); // allocation 2
          villeVisite_i[tab->vpp[i]]=true;
          parcours p_i = ajouterParcours( p, tab->vpp[i] ); // allocation 3
     
          parcourir(p_i, nb_villes, k,  villeVisite_i);
     
     
          memoire_liberer(villeVisite_i); // liberation 1
          memoire_liberer(p_i->itineraire); // liberation 2
        }
         memoire_liberer(tab->vpp); // liberation 3
     
      }
    }
    Merci d'avance pour vos contributions

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tagsOf Voir le message
    Bonjour à tous,

    Je rencontre actuellement un problème avec les libérations dans une de mes fonctions récursive, à t'on le droit d'allouer et liberer de cette manière:

    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
     
    void parcourir(parcours p, int nb_villes, int k,  bool * villeVisite){
     
      if(p->niveau == nb_villes){
        double dp=distanceParcours(p);
        for(int i=0; i<nb_villes; i++)
          printf("%d ",p->itineraire[i]);
        printf("%f \n",dp);
        if(dp < min->distance){
          min->distance = dp;
          copierItineraire(min->itineraire, p->itineraire, nb_villes);
        }
      }
     
      else{
        k_villes_pp tab = k_villesPlusProches( p->itineraire[p->niveau], villeVisite, k, nb_villes ); // allocation 1
        for(int i=0; i < k && i < tab->nb_vpp ; i++){
          bool * villeVisite_i = dupliquer(villeVisite, nb_villes); // allocation 2
          villeVisite_i[tab->vpp[i]]=true;
          parcours p_i = ajouterParcours( p, tab->vpp[i] ); // allocation 3
     
          parcourir(p_i, nb_villes, k,  villeVisite_i);
     
     
          memoire_liberer(villeVisite_i); // liberation 1
          memoire_liberer(p_i->itineraire); // liberation 2
        }
         memoire_liberer(tab->vpp); // liberation 3
     
      }
    }
    Merci d'avance pour vos contributions
    La règle est très simple: toute mémoire que tu alloues doit être libérée quand tu n'en as plus besoin. Apparemment tu alloues p_i dans ta boucle mais tu ne le libères jamais...
    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
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut
    pi est liberer lors de la liberation 2 (voir commentaire), en réalité mon problème surviens lors de la libération ... Si je ne libère pas, je ne rencontre aucun problème ... C'est ca que je ne comprend pas, je me demande si c'est du a la récursivité ...

    Vous en pensez quoi ?

    Merci pour ta contribution

  4. #4
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Poste un code qui compile s'il te plaît.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut
    Voici le code complet qui compile ( il y a juste a modifier memoire_allouer par malloc et memoire_liberer par free).

    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
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <memoire.h>
    #include "tsph.h"
     
    #define INFINI 99999999
     
    typedef struct chemin * chemin;
    typedef struct parcours *parcours;
    typedef struct k_villes_pp *k_villes_pp;
     
    struct chemin{
      int * itineraire;
      double distance;
    };
     
    struct parcours{
      int * itineraire;
      int niveau;
    };
     
    struct k_villes_pp{
      int * vpp;
      int nb_vpp;
    };
     
    static chemin min=NULL;
    static double ** matrice=NULL;
     
    /*------------------------------------------------------------------------------------*/
    static void
    libererK_villes_pp(k_villes_pp k){
      memoire_liberer(k->vpp);
      memoire_liberer(k);
    }
     
    static void
    libererParcours(parcours p){
      memoire_liberer(p->itineraire);
      memoire_liberer(p);
    }
     
    static void
    copierItineraire(int * itineraireA, int * itineraireB, int nb_villes){
      for(int i=0; i< nb_villes; i++)
        itineraireA[i]=itineraireB[i];
    }
     
    static parcours
    creerParcours(){
      parcours p=memoire_allouer(sizeof(struct parcours));
      p->itineraire=memoire_allouer(1* sizeof(int));
      p->itineraire[0]=0;
      p->niveau=1;
      return p;
    }
     
    static bool * 
    creerTab2Bool(int nb_villes){
      bool * tab=memoire_allouer(nb_villes*sizeof(*tab));
      tab[0]=true;
      for(int i=1; i<nb_villes; i++)
        tab[i]=false;
      return tab;
    }
     
    static bool *
    dupliquer(bool * villeVisite, int nb_villes){
      bool * copie=memoire_allouer(nb_villes*sizeof(*copie));
      for(int i=0; i < nb_villes; i++)
        copie[i]=villeVisite[i];
      return copie;
    }
     
    static parcours
    ajouterParcours(parcours p, int id_ville){
      parcours copie=memoire_allouer(sizeof(struct parcours));
      copie->itineraire=memoire_allouer((p->niveau+1) * sizeof(int));
      for(int i=0; i < p->niveau; i++)
        copie->itineraire[i] = p->itineraire[i];
      copie->itineraire[p->niveau]=id_ville;
      copie->niveau=p->niveau +1;
      return copie;
    }
     
    static double 
    distanceParcours(parcours p){
      double dist=0;
      for(int i=0; i < p->niveau -1 ; i++){
        int ville_i=p->itineraire[i];
        int ville_i_1=p->itineraire[i+1];
        dist += matrice[ville_i][ville_i_1];
      }
      dist += matrice[ p->itineraire[p->niveau-1] ][ 0 ];
      return dist;
    }
     
     
    static k_villes_pp
    k_villesPlusProches(int id_ville, bool * villeVisite, int k, int nb_villes){
      int cpt=0;
      for(int i=0; i < nb_villes; i++)
        if(!villeVisite[i])
          cpt++;
      if(cpt < k)
        k=cpt; 
      k_villes_pp villepp= memoire_allouer(sizeof(struct k_villes_pp));
      villepp->vpp=memoire_allouer( k * sizeof(int));
      villepp->nb_vpp=k;
      bool * copie=dupliquer(villeVisite, nb_villes);
     
      double min=INFINI; 
      int ind_min;
      for(int i=0; i < k; i++){
     
        for(int j=0; j < nb_villes; j++)
          if(!copie[j] && matrice[id_ville][j] < min){
    	min = matrice[id_ville][j];
    	ind_min=j;
    	copie[j]=true;
          }
     
        villepp->vpp[i]=ind_min;
        min=INFINI;
      }
      memoire_liberer(copie);
      return villepp;
    }
     
     
    /*------------------------------------------------------------------------------------*/
    void parcourir(parcours p, int nb_villes, int k,  bool * villeVisite){
     
      if(p->niveau == nb_villes){
        double dp=distanceParcours(p);
        for(int i=0; i<nb_villes; i++)
          printf("%d ",p->itineraire[i]);
        printf("%f \n",dp);
        if(dp < min->distance){
          min->distance = dp;
          copierItineraire(min->itineraire, p->itineraire, nb_villes);
        }
      }
     
      else{
        k_villes_pp tab = k_villesPlusProches( p->itineraire[p->niveau], villeVisite, k, nb_villes );
        for(int i=0; i < k && i < tab->nb_vpp ; i++){
          bool * villeVisite_i = dupliquer(villeVisite, nb_villes);
          villeVisite_i[tab->vpp[i]]=true;
          parcours p_i = ajouterParcours( p, tab->vpp[i] );
     
          parcourir(p_i, nb_villes, k,  villeVisite_i); 
     
     
          //memoire_liberer(villeVisite_i);
          // libererParcours(p_i);
        }
        //libererK_villes_pp(tab);
     
      }
    }
     
    int main(void){
      memoire_trace(false);
      matrice=memoire_allouer( 4 * sizeof(*matrice));
      for(int i=0; i<4; i++){
        matrice[i]=memoire_allouer( 4 * sizeof(**matrice));
      }
      for(int i = 0; i < 4; i++)
        matrice[i][i] = 0;
     
      matrice[0][1] = 1;
      matrice[0][2] = 1;
      matrice[0][3] = 1;
      matrice[1][0] = 1;
      matrice[1][2] = 2;
      matrice[1][3] = 4;
      matrice[2][0] = 1;
      matrice[2][1] = 2;
      matrice[2][3] = 2;
      matrice[3][0] = 1;
      matrice[3][1] = 4;
      matrice[3][2] = 2;
      for(int i=0; i<4; i++)
        {
        for(int j=0; j<4; j++)
          printf("%f ", matrice[i][j]);
        printf("\n");
        }
      printf("\n");
     
     
      min=memoire_allouer(sizeof(struct chemin));
      min->itineraire=memoire_allouer(4*sizeof(int));
      min->distance=INFINI;
      for(int i=0; i<4; i++)
        min->itineraire[i]=3;
     
      parcours p=creerParcours(0);
      bool * tab= creerTab2Bool(4);
     
      parcourir(p, 4, 2, tab); // appel a la recursion avec k=2
     
      for(int i=0; i<4; i++)
        printf("%d ",min->itineraire[i]);
      printf("\n");
     
      printf("La distance mini est %f \n", min->distance);
     
      printf("La balance memoire est de %d \n", memoire_balance());
      return EXIT_SUCCESS;
     
    }

    J'ai commenté à 3 reprises les libération qui me font l'erreur (COULD NOT ACCESS MEMORY ...), je n'arrive pas à savoir pourquoi ?

  6. #6
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Ce code ne compile pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    main.c:50: attention : function declaration isn"t a prototype
    main.c: In function «k_villesPlusProches":
    main.c:112: attention : declaration of «min" shadows a global declaration
    main.c:27: attention : déclaration est masquée ici
    main.c: Hors de toute fonction :
    main.c:132: attention : no previous prototype for «parcourir"
    main.c: In function «main":
    main.c:164: erreur: implicit declaration of function «memoire_trace"
    main.c:164: attention : nested extern declaration of «memoire_trace"
    main.c:210: erreur: implicit declaration of function «memoire_balance"
    main.c:210: attention : nested extern declaration of «memoire_balance"

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

Discussions similaires

  1. probleme d'allocation dynamique
    Par vince3320 dans le forum C
    Réponses: 10
    Dernier message: 22/04/2004, 16h27
  2. petit pbm allocation dynamique de stringGrid
    Par AnneOlga dans le forum C++Builder
    Réponses: 10
    Dernier message: 17/01/2004, 11h59
  3. Allocation dynamique de structures
    Par fr_knoxville dans le forum C
    Réponses: 8
    Dernier message: 06/05/2003, 21h59
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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