[C/C++] [Langage C] Problème de pointeur

Le côté programmation du développement d'un jeu vidéo.

[Langage C] Problème de pointeur

Messagepar Gandalf » 03 Avr 2008, 13:55

Bonjour tout le monde;

Voilà dans le cadre d'un tp scolaire je dois réaliser un petit programme en langage permettant, à partir d'un labyrinthe modélisé par un fichier texte, de trouver le chemin le plus court entre l'entrée et la sortie.

Malheureusement je n'arrive pas à faire quelque chose qui tourne! C'est même tout l'inverse et ça plante dès le début.

Pour commencer voici comment est modélisé le fameux labyrinthe en mémoire :

Code: Tout sélectionner
[B]typedef struct[/B]{
   [B]int[/B] largeur;       // Largeur du labyrinthe
   [B]int[/B] hauteur;           // Hauteur du labyrinthe
   [B]char[/B] **labyrinthe;  // Le labyrinthe (tableau à deux dimensions)
   [B]int[/B] entre_x;           //Abscisse de l'entré
   [B]int[/B] entre_y;           // Ordonnée de l'entré
   [B]int[/B] sortie_x;       // Abscisse de la sortie
   [B]int[/B] sortie_y;       // Ordonnée de la sortie
} Labyrinthe;


Et pour commencer j'ai deux fonctions :

Labyrinthe_Initialisation : qui à partir du fichier extrait la largeur et la hauteur du labyrinthe, appel la fonction Labyrinthe_Creation (voir la suite) puis copie le labyrinthe. Un exemple de labyrinthe est donnée plus bas.
Code: Tout sélectionner
Labyrinthe * Labyrinthe_Initialisation(FILE * fichier){
   //Initialisation des variable locales
   int largeur, hauteur;
   Labyrinthe * l;
   char buf;
   int i, j;

   //Lecture de la hauteur/largeur du labyrinthe depuis le fichier
   if(fscanf(fichier,"%d %d\n", &largeur, &hauteur) != 2){
      fprintf(stderr, "En-tête du fichier invalide.");
      exit(2);      
   }
            
   //Initialisation du labyrinthe
   l = Labyrinthe_Creation(largeur, hauteur);   
   if(!l){
      fprintf(stderr, "Problème sur l'allocation mémoire du labyrinthe.");
      exit(1);   
   }

   //Debugage
   #ifdef DEBUG
      printf(">>DEBUG > Labyrinthe_Initialisation() > largeur : %d, hauteur : %d \n", l->largeur, l->hauteur);
   #endif
   
   //Copie du labyrinthe depuis le fichier
   for(i=0; i<hauteur; i++){
      for(j=0; j<largeur; j++){
         if(fscanf(fichier, "%c", &buf) != 1){
            fprintf(stderr, "Problème dans la structure du labyrinthe.");
            exit(2);
         }
         else{
            fscanf(fichier, "%c", &buf);
            l->labyrinthe[i][j] = *buf;   
         }
      }
   }

   return l;
}


Labyrinthe_Creation : Permet de créer la structure Labyrinthe en mémoire (je pense que cette fonction marche pas comme elle le devrait...).

Code: Tout sélectionner
Labyrinthe * Labyrinthe_Creation(int largeur, int hauteur){
   Labyrinthe * l;
   l->largeur = largeur;
   l->hauteur = hauteur;

   l->labyrinthe = (char **) malloc(sizeof(char *)*largeur);
   if(!l->labyrinthe){
      fprintf(stderr, "Erreur d'allocation mémoire.");
      exit(1);
   }
      
   int i;
   for(i=0; i<largeur; i++){
      l->labyrinthe[i] = (char *) malloc(sizeof(char)*hauteur);
      if(!l->labyrinthe[i]){
         fprintf(stderr, "Erreur d'allocation mémoire.");
         exit(1);
      }
   }
   
   return (l);   
}


Mon main() :

Code: Tout sélectionner
int main(void){

   //Initialisation des variables
   Labyrinthe * l;
   FILE * f;

   //Chargement du fichier
   f = fopen("lab1.txt", "r");

   //Initialisation du labyrinthe
   l = Labyrinthe_Initialisation(f);
   if(!l){
      fprintf(stderr, "Problème sur l'allocation mémoire du labyrinthe.");
      exit(1);   
   }
   
   #ifdef DEBUG
      printf(">>DEBUG > main() > largeur : %d, hauteur : %d \n", l->largeur, l->hauteur);
   #endif

   //Fermeture du fichier
   fclose(f);             

   return 0;
}


Et enfin un exemple de Labyrinthe :

Code: Tout sélectionner
20 11
********************
*    *             *
* * **** ***********
S *    *           *
****** ********** **
*             *    *
* *********** *** **
*           *      *
**** ****** ***** **
*    *         *   *
******************E*


Quand je compile (je suis sous vista mais j'utilise cygwin et un makefile) j'obtiens :


Code: Tout sélectionner
$ ./Programme.exe
>> DEBUG > Labyrinthe_Initialisation() > largeur : 20, hauteur : 11
        540  [main] Programme 1104 _cygtls::handle_exception: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)


J'imagine que c'est lorsque je crée le tableau à deux dimensions mais je comprend vraiment pas pourquoi et suis totalement déseperé. :00000025:

Je vous remercie d'avance
Avatar de l’utilisateur
Gandalf
Hello World, I'm new !
 
Messages: 316
Inscription: 10 Avr 2005, 10:19
Localisation: Lorraine

Messagepar Tomu » 03 Avr 2008, 14:41

Salut,

J'ai eu a rendre le même tp il y a une semaine, a quelque petite différences près,
Si tu veux que je te montre mon code envois moi un mp ou avoir des explications sur comment j'ai fais.

Sinon pour ce qui est de ton code je ne vois pas trop, essais avec fgetc au lieu de fscanf pour la lecture du labyrinthe.
Le sage montre la lune, et l'idiot regarde le bout du doigt !
Le sage ne dit pas se qu'il sait, alors que l'idiot ne sait pas se qu'il dit !
Tomu
Hello World, I'm new !
 
Messages: 103
Inscription: 18 Juil 2005, 22:41
Localisation: VOSGES 88

Messagepar Gandalf » 03 Avr 2008, 14:57

Finalement j'ai réussit à ce que ça fonctionne (je sais pas vraiment comment), mais je bloque un peu plus loin, avec une fonction qui est censé affiché le labyrinthe elle toute simple :

Code: Tout sélectionner
void Labyrinthe_Affichage(Labyrinthe * lab){
   int i, j;

   #ifdef DEBUG
      printf(">>DEBUG > Labyrinthe_Affichage() > largeur : %d, hauteur : %d \n", lab->largeur, lab->hauteur);
   #endif
   
   for(i=0; i<lab->hauteur; i++){
      for(j=0; j<lab->largeur; j++){
         printf("%c", lab->labyrinthe[i][j]);   
      }
   }
}


Mais les valeurs lab->largeur et lab->hauteur deviennent totalement aberrantes dans la fonction Labyrinthe_Affichage.

Exemple du débug :
Code: Tout sélectionner
>> DEBUG > main() > largeur : 5, hauteur : 5
>> DEBUG > Labyrinthe_Affichage > largeur : 1628447136 hauteur : 4200144

(c'est plus le même labyrinthe que dans mon premier post les dimenssions son bien de 5x5)

Dans mon main() j'ai juste rajouter :

Code: Tout sélectionner
Labyrinthe_Affichage(l);


Pourquoi les valeurs change-t-elles?
Avatar de l’utilisateur
Gandalf
Hello World, I'm new !
 
Messages: 316
Inscription: 10 Avr 2005, 10:19
Localisation: Lorraine

Messagepar Mokona » 03 Avr 2008, 16:16

Code: Tout sélectionner
   Labyrinthe * l;
   l->largeur = largeur;
   l->hauteur = hauteur;


Ce code est faux.

"Labyrinthe * l;" déclare un pointeur sur la structure Labyrinthe. Par contre, cela ne réserve absolument aucun espace pour la structure. Juste pour son pointeur.

"l" pointe donc vers quelque chose de non défini. Et les affectations suivantes ("l->largeur = largeur;") se font... quelque part en mémoire.

Par chance, cet endroit (non réservé, je le rappelle et complètement indéfini) n'est pas tout de suite écrasé.

Mais il l'est quand tu arrives dans ton affichage.

Remplace donc

Code: Tout sélectionner
Labyrinthe * l;


Par quelque chose comme

Code: Tout sélectionner
Labyrinthe * l = malloc(sizeof(Labyrinthe));
Mokona
Hello World, I'm new !
 
Messages: 1686
Inscription: 13 Mar 2005, 13:00

Messagepar Gandalf » 03 Avr 2008, 17:01

Ah ok! Merci beaucoup Mokona! Maintenant ça marche et je progresse petit à petit. J'ai recommencé presque depuis le début et je n'utilise plus de double pointeurs pour mon tableau deux dimensions (trop complexe ^^'). Par contre y a un truc que j'arrive pas à faire:

J'ai une fonction,

void Labyrinthe_Cherche_Entree(Labyrinthe * lab)

qui doit modifier les valeurs contenue dans mon tableau lab->labyrinthe[] normalement c'est possible vu que c'est l'adresse de la structure qui est passé en paramètre et je pensais faire un truc du genre :

*lab->labyrinthe[x] = 'a';

mais ça marche pas :S
Avatar de l’utilisateur
Gandalf
Hello World, I'm new !
 
Messages: 316
Inscription: 10 Avr 2005, 10:19
Localisation: Lorraine

Messagepar wetneb » 03 Avr 2008, 17:22

Vu le prototype de la fonction, pas besoin de * devant ton pointeur.
C'est soit :
(*lab).labyrinthe[x] = 'a';
soit
lab->labyrinthe[x] = 'a';

La deuxième syntaxe étant beaucoup plus utilisée, évidemment.
Avatar de l’utilisateur
wetneb
Hello World, I'm new !
 
Messages: 130
Inscription: 09 Fév 2006, 19:17


Retourner vers Programmation

Qui est en ligne

Utilisateurs parcourant ce forum: Google [Bot] et 6 invités

cron