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

Langage C++ Discussion :

problème avec la méthode size d'une std::list


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut problème avec la méthode size d'une std::list
    Bonjour à tous
    Je me heurte actuellement à un problème. Je suis en train de coder un jeu avec la SFML dont les grandes lignes n'apporteront rien à la résolution de mon problème. En fait, je dispose d'une classe Image_pack qui contient une list d'images sfml et une liste d'une autre classe qui permet de lier un pointeur sur image avec un index et un nom. Le code des 2 classes sera sans doute plus clair : (pour des raisons de simplicité, les 2 classes sont dans le même fichier)
    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
     
    //image_pack.hpp
    //image_pack + Image_id_index
    #ifndef IMAGE_PACK_HPP
    #define IMAGE_PACK_HPP
     
    #include <SFML\Graphics.hpp>
    #include <list>
    #include <iostream>
     
    using namespace sf;
    using namespace std;
     
    class Image_id_index
    {
        public:
            Image_id_index(Image *img, int index, string id);
     
            int get_index() const;
            string get_name() const;
            Image *get_img_adress();
     
        private:
            Image *m_img;
            int m_index;
            string m_name;
    };
     
    class Image_pack
    {
        public:
            Image_pack();
     
            bool push_back(string img_path, int index, string id);
     
            Image *getImage(int index);
            Image *getImage(string id);
     
        private:
            list<Image_id_index> m_t_image_id_index;
            list<Image> m_t_image;
    };
     
    #endif
    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
     
    //image_pack.cpp
     
    #include "image_pack.hpp"
     
    Image_id_index::Image_id_index(Image* img, int index, string id) :
                                    m_index(index),
                                    m_name(id),
                                    m_img(img)
    {
        cout<<index<<" "<<id<<" "<<m_img<<endl;
    }
     
    int Image_id_index::get_index() const
    {
        return m_index;
    }
     
    string Image_id_index::get_name() const
    {
        return m_name;
    }
     
    Image *Image_id_index::get_img_adress()
    {
        return m_img;
    }
     
    Image_pack::Image_pack()
    {}
     
    bool Image_pack::push_back(string img_path, int index, string id)
    {
        Image img;
        if(!img.LoadFromFile(img_path.c_str()))
        {
            cout<<"Le fichier ressource est corrompu ou l'image n'existe pas"<<endl;
            return false;
        }
     
        m_t_image.push_back(img);
        list<Image>::iterator i = m_t_image.end();
        i--;
        m_t_image_id_index.push_back(Image_id_index(&(*i),index,id));
        return true;
    }
     
    Image * Image_pack::getImage(int index)
    {
        cout<<index<<" ";
        cout<<m_t_image_id_index.size()<<endl;
        for(list<Image_id_index>::iterator it = m_t_image_id_index.begin();it!=m_t_image_id_index.end();it++)
            if(it->get_index() == index)
                return it->get_img_adress();
        return NULL;
    }
     
    Image * Image_pack::getImage(string id)
    {
        for(list<Image_id_index>::iterator it = m_t_image_id_index.begin();it!=m_t_image_id_index.end();it++)
            if(it->get_name() == id)
                return it->get_img_adress();
        return NULL;
    }
    L'utilisation de la classe Image_pack est la suivante :
    au début du jeu, une classe déclare une instance de Image_pack puis charge à partir d'un fichier toutes les données nécessaires pour ajouter des images à l'instance créée, comme ceci :

    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
     
    void MainWindow::load_resources(string file_name)
    {
        ifstream stream(file_name.c_str(),ios::in);
     
        if(stream == NULL)
        {
            cout<<endl<<"Fichier introuvable, gestion des ressources impossible"<<endl;
            m_quit = true;
        }
        else
        {
            string filepath;
            string name;
            int index;
     
            while(stream>>filepath>>name>>index && m_quit == false)
            {
                cout<<"chargement de l'image : "<<endl<<"- chemin d'acces : "<<filepath<<endl<<"- nom : "<<name<<endl<<"- index : "<<index<<endl<<endl;
                if(!m_img_pack->push_back(filepath,index,name))
                    m_quit = true;
            }
     
            if(!stream.eof())
            {
                cout<<"Le fichier ressources est corrompu, les ressources n'ont pas pu etre chargees"<<endl;
                m_quit = true;
            }
        }
    }
    Ensuite, le pack est donné en paramètre à de nombreuses autres classes qui utiliseront par l'index ou le nom les images contenues dans ce pack. Sauf que tout ne se passe pas comme prévu : une erreur vraiment bizarre s'est glissée dans mon programme. En effet, lorsque j'essaie d'utiliser la fonction getImage(int index) du pack, le programme s'arrête de fonctionner. Divers tests avec le deboggeur m'ont permis d'en déduire que cela provenait vraisemblablement de l'appel aux méthodes de la list<Image_id_index> que sont size(), begin() et end() (size pour confirmer ce bug). Je ne sais vraiment pas du tout à quoi cela peut-il être du car l'appel à ces méthodes dans la fonction push_back du pack fonctionne parfaitement . Je précise que cela ne peut pas venir d'un index faux puisque l'appel à ces méthodes survient avant les possibles erreurs liées à un index trop élevé.
    Pouvez-vous m'aider ? Merci par avance

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    list<Image>::iterator i = m_t_image.end();
    i--;
    C'est moche ça !! Je te déconseille fortement d'utiliser ce genre de choses, std::list a une fonction qui s'appelle back() et qui fait ce que tu veux (récupérer le dernier élément).
    De plus, as-tu vérifié que le constructeur par copie de la classe Image, ainsi que l'opérateur d'assignation de cette classe sont définis correctement ? S'ils ne le sont pas je te conseille de stocker dans m_t_image des pointeurs sur Image (sinon le comportement est indéfini).
    En tout cas, le fait de récupérer un pointeur sur un élément d'une liste n'est pas une chose à faire, car la STL fait tout un bordel avec les éléments que tu donnes à ses conteneurs (c'est d'ailleurs pour cela que le constructeur par copie et l'opérateur d'assignation de ces éléments doivent être définis correctement). Donner un iterateur (à ton constructeur de Image_id_index) sur l'élément ne serait pas non plus une solution car les itérateurs sont modifiés à la moindre modification du contenu de la list.

    Donc, tout ça pour dire que dans m_t_image tu devrais stocker des pointeurs sur Image (nus ou managés, ça importe peu, si tant est que tu désalloues bien les pointeurs nus).

    Pour moi les problèmes que tu rencontres viennent donc certainement de :
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_t_image_id_index.push_back(Image_id_index(&(*i),index,id));
    que je réécrirais ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    list<Image *> m_t_image;
    et
    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
     
    // Ajout d'un constructeur par copie et d'un operateur d'assignation pour Image_id_index
    Image_id_index::Image_id_index( const Image_id_index & p_image)
    	:	m_img( p_image.m_img)
    	,	m_index( p_image.m_index)
    	,	m_name( p_image.m_name)
    {
    }
     
    Image_id_index & Image_id_index::operator =( const Image_id_index & p_image)
    {
    	m_img = p_image.m_img;
    	m_index = p_image.m_index;
    	m_name = p_image.m_name;
    }
     
    bool Image_pack::push_back( const string & img_path, int index, const string & id)
    {
    	Image * pImg = new Image;
    	if( ! pImg->LoadFromFile(img_path.c_str()))
    	{
    		cout<<"Le fichier ressource est corrompu ou l'image n'existe pas"<<endl;
    		delete pImg;
    		return false;
    	}
     
    	m_t_image.push_back( pImg);
    	m_t_image_id_index.push_back( Image_id_index(pImg,index,id));
    	return true;
    }
     
    //Ajout d'une fonction cleanup permettant de supprimer tout le bordel
    void Image_pack::cleanup()
    {
    	for (list<Image>::iterator it = m_t_image.begin() ; it != m_t_image.end() ; ++it)
    	{
    		delete ( * it);
    	}
    	m_t_image.clear();
    	m_t_image_id_index.clear();
    }
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Donner un iterateur (à ton constructeur de Image_id_index) sur l'élément ne serait pas non plus une solution car les itérateurs sont modifiés à la moindre modification du contenu de la list.
    C'est vrai sur les vecteurs, mais les list assurent une certaine stabilité de leurs itérateurs (et du coup des pointeurs sur les éléments).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    C'est vrai sur les vecteurs, mais les list assurent une certaine stabilité de leurs itérateurs (et du coup des pointeurs sur les éléments).
    OK, bon à savoir, ça. (dans mon code je ne fais généralement pas confiance à la stabilité des itérateurs sur les conteneurs STL)
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  5. #5
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    Merci pour ces éléments que je viens de tester

    J'ai réécris le .cpp (et le .hpp) en prenant compte de ce que tu m'as dit, du moins je le pense :

    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
     
    #include "image_pack.hpp"
     
    Image_id_index::Image_id_index(Image* img, int index, string id) :
                                    m_index(index),
                                    m_name(id),
                                    m_img(img)
    {
        cout<<index<<" "<<id<<" "<<m_img<<endl;
    }
     
    Image_id_index::Image_id_index(const Image_id_index & p_image)	:
                m_img(p_image.m_img),
                m_index(p_image.m_index),
                m_name(p_image.m_name)
    {
    }
     
    int Image_id_index::get_index() const
    {
        return m_index;
    }
     
    string Image_id_index::get_name() const
    {
        return m_name;
    }
     
    Image *Image_id_index::get_img_adress()
    {
        return m_img;
    }
     
    Image_pack::Image_pack()
    {}
     
    Image_pack::~Image_pack()
    {
        for(list<Image*>::iterator it = m_t_image.begin();it!=m_t_image.end();it++)
            delete (*it);
        for(list<Image_id_index*>::iterator it = m_t_image_id_index.begin();it!=m_t_image_id_index.end();it++)
            delete (*it);
    }
     
    bool Image_pack::push_back(string img_path, int index, string id)
    {
        Image *img = new Image();
        if(!img->LoadFromFile(img_path.c_str()))
        {
            cout<<"Le fichier ressource est corrompu ou l'image n'existe pas"<<endl;
            delete img;
            return false;
        }
     
        m_t_image.push_back(img);
        m_t_image_id_index.push_back(new Image_id_index(img,index,id));
        return true;
    }
     
    Image * Image_pack::getImage(int index)
    {
        cout<<index<<" ";
        cout<<m_t_image_id_index.size()<<endl;
        for(list<Image_id_index*>::iterator it = m_t_image_id_index.begin();it!=m_t_image_id_index.end();it++)
            if((*it)->get_index() == index)
                return (*it)->get_img_adress();
        return NULL;
    }
     
    Image * Image_pack::getImage(string id)
    {
        for(list<Image_id_index*>::iterator it = m_t_image_id_index.begin();it!=m_t_image_id_index.end();it++)
            if((*it)->get_name() == id)
                return (*it)->get_img_adress();
        return NULL;
    }
    Cependant, le même bug subsiste, celui qui fait planter le programme en essayant d'acceder à la méthode size() de la liste ... J'ai également remplacé la list par un vector mais le problème persiste ! Je dois avouer que je ne comprends pas du tout pourquoi !

    Edit : ceci ne marche pas non plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    bool Image_pack::push_back(string img_path, int index, string id)
    {
        m_t_image.push_back(new Image());
        if(!(m_t_image.back())->LoadFromFile(img_path.c_str()))
        {
            cout<<"Le fichier ressource est corrompu ou l'image n'existe pas"<<endl;
            return false;
        }
     
        m_t_image_id_index.push_back(new Image_id_index((m_t_image.back()),index,id));
        return true;
    }

  6. #6
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    As-tu bien vérifié que ton pointeur sur Imge_pack a été initialisé ? (via un new si dynamique)
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

Discussions similaires

  1. [XL-2010] Problème avec la méthode find d'un objet Range dans une zone filtrée
    Par stargates01 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 28/02/2014, 23h27
  2. Problème avec ma méthode de recherche dans une JList
    Par Invité dans le forum Composants
    Réponses: 4
    Dernier message: 24/07/2007, 10h33
  3. [Système] Problème avec les méthodes d'une classe
    Par oussama127 dans le forum Langage
    Réponses: 7
    Dernier message: 30/08/2006, 09h18
  4. problème avec la méthode getElementById() dans Firefox
    Par matrouba dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/12/2005, 08h55
  5. Problème avec la méthode pack()
    Par tomca dans le forum Langage
    Réponses: 5
    Dernier message: 15/09/2005, 10h58

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