Partage
  • Partager sur Facebook
  • Partager sur Twitter

Erreur spécifique à Windows?

    21 octobre 2008 à 19:36:46

    Bonjour à tous

    J'en viens à vous demander votre avis car je sais plus trop quoi faire. Je vais essayer de vous exposer ça le plus clairement possible.

    J'ai deux classes, Image et Zone comme suit

    class Zone
    {
         int x1, y1, x2, y2; //points délimitant la zone
         Pixel *z_data;
    }
    


    class Image
    {
         Pixel *i_data;
         std::vector<Zone> i_zoneList;
    
         /*...*/
    
         Image::diviser()
         {
              i_zoneList.push_back(Zone(x1, y1, x2, y2, i_data));
         }
    
    }
    



    Le soucis c'est qu'une fois une instance Zone créée, il m'est impossible d'accéder aux éléments de z_data. Il semble que z_data pointe n'importe où, entraînant une erreur de segmentation. En revanche, les autres champs sont parfaitement accessibles.

    Et le truc bizarre c'est qu'un pote compile et exécute mon code sans problème sous Linux. J'ai essayé de changer le nom de la variable "data" (au cas où y'en aurait une portant ce nom), rien n'y fait.

    Dois-je en conclure qu'il s'agit d'un problème spécifique à Windows? Qq'un a déjà eu un problème similaire et l'a réglé?

    Tout avis est bienvenu :)

    Merci.

    PS: Je programme sous Dev-C++.
    PPS: Je posterai plus de code si necessaire, mais le problème ne semble pas venir de là.
    PPPS: Ceci n'est pas mon vrai code (d'ailleurs il comporte des fautes), j'en ai simplement écrit un nouveau pour qu'il soit plus clair.
    • Partager sur Facebook
    • Partager sur Twitter
      22 octobre 2008 à 0:41:24

      Bonjour !

      Je me trompe peut etre, mais : *z_data n'est pas initialisé il me semble... Ou alors il manque le morceau en question (Constructeur ..) .. non ?

      Sinon difficile à dire : Si j'ai bien compris ton code est normalement plus complet, essaye de retirer un à un les élèments qui semble générer ton erreur pour le localier, et si tu ne vois pas en quoi ca engendre une erreur, refais un tour par ici.. Au pire, si tu ne vois pas ce qui engendre une erreur, poste plus de code !

      Bonne chance.
      • Partager sur Facebook
      • Partager sur Twitter
        22 octobre 2008 à 0:45:50

        Je vois deux possibilités qui pourraient expliquer le phénomène:

        Possibilité N°1:

        Sous Windows l'initialisation du pointeur échoue, mais tu n'as pas de contrôle d'erreur, donc tu continues avec un pointeur invalide. Le cas typique est le cas du pointeur initialisé à partir de données se trouvant dans un fichier. Pour une raison quelconque la lecture du fichier échoue (au hasard parce que le fichier n'est pas où on va le chercher) et le pointeur est nul ou invalide.

        Possibilité N°2:

        Le bloc de mémoire sur lequel pointent tes pointeurs est libéré quelque part dans ton programme de ce fait tes pointeurs sont invalides sous Windows comme sous Linux. Tu crois que ton programme tourne bien sous Linux, parce que l'allocateur mémoire utilisé, n'a pas encore recyclé la mémoire libérée quand tu essaies d'y accéder. Sous Windows en revanche, l'allocateur a recyclé la mémoire donc ton pointeur pointe sur des données qui ne sont pas ce qu'elles devraient être et c'est le drame.

        • Partager sur Facebook
        • Partager sur Twitter
        Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
          22 octobre 2008 à 2:33:45

          Merci de vos réponses :)

          Mon pointeur *z_data est bien initialisé dans le constructeur, et pas à partir de données situées dans un fichier.

          Voilà un peu plus de code de la classe Zone, en espérant que ça aide.

          class Zone
          {
               int z_x1, z_y1, z_x2, z_y2;
               Pixel *z_data;
          
               Zone::Zone(int x1, int y1, int x2, int y2, Pixel *data)
               {
                    z_x1 = x1;
                    z_y1 = y1;
                    z_x2 = x2;
                    z_y2 = y2;      
                    z_data = data;
                    cout << "Avant:" << z_data << endl;
          	
               }
          
               void Zone:: displayData()
               {
                    cout << "Apres:" << z_data << endl;
               }
          }
          


          Ensuite cette fonction est appellée dans ma classe Image comme ça:

          class Image
          {
               int i_width, i_height, i_size;
               Pixel *i_data;
               vector<Zone> i_zoneList;
          
               void Image::split(x1, y1, x2, y2)
               {
                    /*Calcul pour trouver les points*/
          
                    i_zoneList.push_back(Zone(x11, y11, x12, y12, i_data));
                    i_zoneList.push_back(Zone(x21, y21, x22, y22, i_data));
                    i_zoneList.push_back(Zone(x31, y31, x32, y32, i_data));
                    i_zoneList.push_back(Zone(x41, y41, x42, y42, i_data));     
               }
          
               void Image::displayZone()
               {
                    for (i=0; i<i_zoneList.size(); i++)
                         i_zoneList[i].displayData();     
               }
          }
          

          1)Bien évidemment, ma fonction displayZone() est appelée après split (donc la liste n'est pas vide)
          2)Dans mon constructeur Zone j'affiche les adresses des pointeurs des différentes instances créées (qui pointent logiquement toutes au même endroit). Une fois sorti du constructeur, lorsque j'affiche ces adresses par la fonction displayData(), elles sont toutes différentes.
          3)Lors de l'exécution de *ce* code je n'ai pas de segmentation fault car je n'accède pas aux éléments de z_data d'une instance zone. Mais dès que j'essaye d'y accéder, ça plante.
          4)Petite info, lorsque je créé les instances Zone (et que je veuille accéder aux éléments de z_data, ou non), j'ai cette erreur quand je quitte mon programme (en appuyant sur echap, mon programme comprennant une fenetre GLut)

          Merci :)
          • Partager sur Facebook
          • Partager sur Twitter
            23 octobre 2008 à 16:26:42

            Salut, est ce que, a tout hasard t'aurais psa un problème de libération de mémoire, ou de pointeur qui pointe vers un objet qui n'existe pas.

            je n'ai pas bien compris tout ce que tu fais, mais quand tu fais
            z_data = data;
            dans ton constructeur, tu ne fais que copier l'adresse, tu dois être sur que d'une manière ou d'un autre, les données pointés sont encores valides et ne sont pas détruites au moment où tu t'en sers.

            Que fais le destructeur?

            Qui crée vraiment l'objet pointé par z_data (le new il est ou?) et qui le détruit?
            • Partager sur Facebook
            • Partager sur Twitter
              24 octobre 2008 à 1:06:35

              Salut

              Le pointeur i_data pointe bien sur quelque chose. Et c'est cette adresse que je copie dans mes instances Zone en faisant z_data = data (classe Image lignes 11, 12, 13, 14).

              Le constructeur d'Image est un peu long et pas très clair au premier coup d'œil. Je le mets quand même mais je sais pas si c'est bien la peine :)
              Mais encore une fois, i_data ne pointe pas sur rien; j'arrive à accéder à ses éléments. Même, et c'est ça qui est vraiment bizarre, c'est que dans le constrcuteur Zone, z_data pointe bien la même chose que i_data (classe Zone - ligne 13) et ce pour les 4 instances que je créé. J'arrive bien à accéder aux éléments de z_data.
              En revanche ce n'est plus le cas hors du constructeur (classe Zone - ligne 19), une fois que les instances ont été créées; elles pointent n'importe où (d'où mon erreur de segmentation quand je veux accéder aux éléments) et toutes les instances pointent sur qq chose de différent :-°

              Dsl, mais j'ai vraiment le truc de tjrs me choper des erreurs incompréhensibles. Merci de m'aider :)


              Image::Image(char *nom)
              {
              FILE *f;
              char s[MAXLIGNE];
              int width, height, maxgrey, n, k;
              unsigned char ligne[2048];
              	            
              	/* Ouverture du fichier */
              	f = fopen (nom, "rb");
              	if (f == NULL)
              	{
              		printf ("ERREUR fopen(%s)\n", nom);
              	}
              	    
              
              	fgets (s, MAXLIGNE, f);
              	if (s[0] != 'P' || s[1] != '5')
              	{
              		printf ("ERREUR MagicValue <> P5\n");
              		fclose (f);
              	}
              	 
              	/* Lecture width height*/
              	do fgets (s, MAXLIGNE, f);
               		while (s[0] == '#');
               	sscanf (s, "%d %d", &width, &height);
              	    
              	/* Lecture maxgrey
              	* On ne tient pas compte de maxgrey, qui est presque toujours 255.
              	* On saute les ligne commencant par un '#' */
              	do fgets (s, MAXLIGNE, f);
              		while (s[0] == '#');
              	sscanf (s, "%d", &maxgrey);
              	        
              
              	
              	
              	/* Creation de l'image */
              	i_width = width;
              	i_height = height;
              	i_size = width * height;
              	i_data = (Pixel*) malloc (width * height * sizeof(Pixel));
              	            
              	for (n=0; n<height; n++)
              	{
              		fread(ligne,sizeof(unsigned char)*width,1,f);
              		for (k=0; k<width; k++)
              		{
              			i_data[n*width+k]=(Pixel)ligne[k];
              		}
              	}
              	    
              	fclose (f);
              }
              
              • Partager sur Facebook
              • Partager sur Twitter

              Erreur spécifique à Windows?

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown