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 :

SIGSEGV sur une std::map::find();


Sujet :

Langage C++

  1. #1
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut SIGSEGV sur une std::map::find();
    Bonjour !

    Ca fait un petit peu de temps que je suis sur cette erreur, et je vois pas du tout vers ou me tourner pour resoudre ca.

    Voici la fonction qui m'envoie ce demon ! (En gras, l'erreur SIGSEGV)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    void Clips::addClip(string g, SDL_Rect* r)
    {
        if(_spr->rects.find(g) == _spr->rects.end())
        {
            _spr->rects.insert(make_pair(g, vector<SDL_Rect*>()));
        }
        _spr->rects.find(g)->second.push_back(r);
        ++_spr->scount;
        if(_spr->index < 0) { _spr->index = 0; }
        _spr->ci = _spr->rects[g].begin();
    }
    Voici egalement toute la definition, ainsi que le constructeur
    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
     
    struct __sprite {
        map<string, vector<SDL_Rect*>> rects;
        string group;
        int index;
        int scount;
        int gcount;
        bool loop; // true = animate to RIGHT, false = to LEFT
        bool _autoanimate;
        vector<SDL_Rect*>::iterator ci;
    };
    class Clips {
        public:
            Clips();
            void addClip(string g, SDL_Rect* r);
            void loopTo(bool dir) { _spr->loop = dir; }
            void autoanimation(bool anim) { _spr->_autoanimate = anim; }
            bool autoanimate() { return _spr->_autoanimate; }
            void refreshiterator();
            SDL_Rect* get();
            void setgroup(string g) { _spr->group = g; refreshiterator(); }
            string group() { return _spr->group; }
            bool hoverable() { return !_spr->_autoanimate; }
        private:
            void nextclip();
            __sprite* _spr;
    };
    Constructeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Clips::Clips()
    {
     
        shared_ptr<__sprite> _spr(new __sprite);
        _spr->_autoanimate = false;
        _spr->loop = true;
        _spr->scount = 0;
        _spr->gcount = 0;
        _spr->index = -1;
        _spr->group = "";
    }
    Voici également le resultat du débug !
    #0 0046D083 std::_Rb_tree<std::string, std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > >, std::_Select1st<std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > > > >::_M_begin(this=0xbaadf00d) (c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482)
    #1 0046CF64 std::_Rb_tree<std::string, std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > >, std::_Select1st<std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > > > >::find(this=0xbaadf00d, __k=@0x28fbb4) (c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:1421)
    #2 00469995 std::map<std::string, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::vector<SDL_Rect*, std::allocator<SDL_Rect*> > > > >::find(this=0xbaadf00d, __x=@0x28fbb4) (c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_map.h:659)
    #3 00404132 Clips::addClip(this=0x915238, g={static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x915284 "stand"}}, r=0x915258) (D:\C++\projects\Client v2\Factories\Tools.cpp:16)
    #4 00406072 __WFSprite(this=0x9150b8, spritesheet={static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x28fca8 "\224P\221"}}, p={x = 200, y = 200}, s={x = 80, y = 140}) (D:\C++\projects\Client v2\Factories\Widgets\WFSprite.cpp:16)
    #5 00423F98 WidgetFactory::Create<__WFSprite>(this=0x914d30, spritesheet={static npos = 4294967295, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x915094 "sprite.bmp"}}, p={x = 200, y = 200}, s={x = 80, y = 140}) (D:/C++/projects/Client v2/Factories/WidgetFactory.h:29)
    #6 00408516 GUIManager::Show(this=0x913480) (D:\C++\projects\Client v2\GUIManager.cpp:61)
    #7 00408903 SDL_main(argc=1, argv=0x912fa0) (D:\C++\projects\Client v2\main.cpp:14)
    #8 00409E49 console_main(argc=1, argv=0x912fa0) (./src/main/win32/SDL_win32_main.c:210)
    #9 00000000 0x00000001 in ??() (???)
    #10 00000000 0x0000001b in ??() (???)
    #11 00000000 0x00000000 in ??() (???)
    Apparement, le programme essaye d'acceder a la map, alors qu'elle n'a pas de memoire ?!
    Pourtant, jj'ai lu un truc sur google (d'où le shared_ptr !)

  2. #2
    Membre actif Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Points : 281
    Points
    281
    Par défaut
    Dans la classe, _spr est un pointeur normal. Dans le constructeur tu créé un shared_ptr, qui est détruit à la fin du constructeur, et la sprite avec puisqu'il n'y a pas d'autre shared_ptr dessus.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu n'initialise pas la variable membre _spr dans ton constructeur (d'aiileurs pourqui utiliser un pointeur ? pour faire un pimpl ?), c'est une variable locale du même nom qui est initialisée.
    _spr pointe donc vers n'importe où et dès que tu essayes d'y accéder tu as un segmentation fault. Pour ce genre d'erreur, "0xbadf00d" peut te mettre la puce à l'oreille ( voir ici )

  4. #4
    Membre régulier
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Points : 99
    Points
    99
    Par défaut
    J'ai enlevé le pointeur, est ca supprime le SIGSEGV (apparement)


    Faux espoir.


    Le SIG* se déplace, et je remonte plus haut dans le programme !
    Il s'est transformé en SIGILL

    Le premier appel se trouve ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WidgetFactory::getInstance()->Create<__WFSprite>((string)"sprite.bmp", oPos({200,200}), oSize({80,140}))
    Voici le template utilisé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename _WidgetClass>
            pair<string, Widget*> Create(string spritesheet, oPos p, oSize s)
            {
                return make_pair(UniqueID(), new _WidgetClass(spritesheet, p, s));
            }
    MArche bien également.
    donc, la je fais en locurence un new __WFSprite(string, opos, osize);

    Voici le constructeur de __WFSPrite
    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
    __WFSprite::__WFSprite(string spritesheet, oPos p, oSize s)
    {
        // surface
        SDL_Surface* surf = load_image(spritesheet);
        // size, position
        SDL_Rect* sandp = CreateRect(s.x, s.y, p.x, p.y);
        // sprite sheet cut
        SpriteSheet clips;
        // for now
        // groups = 1
        // clips = 4
        for(int i = 0; i < 4 ; ++i)
        {
            clips.addClip("stand", CreateRect(i*sandp->w+i*1, 0, sandp->w, sandp->h));
        }
        clips.autoanimation(true);
        // creating widget
        Widget(UniqueID(), surf, NULL, sandp, &clips, NULL, false, true); // SIGILL
        char t[50];
        sprintf(t, "size of clips is %d", _ss->getgroup());
        MessageBox(NULL, t, "sprite", MB_OK);
    }
    Note: __WFSprite herite publiquement de Widget, donc voici le header de Widget:

    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
    class Widget
    {
        public:
            //ctor
            Widget(string id, SDL_Surface* sprite, SDL_Surface* dest, SDL_Rect* sandp, SpriteSheet* c, funcptr callback, bool focusable, bool autoanimate) :
                _id(id),
                _sprite(sprite),
                _dest(dest),
                _sandp(sandp),
                _ss(c),
                _callback(callback),
                _focusable(focusable)
            {};
            // var set
            void SetDest(SDL_Surface* dst);
            void SetCallback(funcptr fptr);
            // clip call
            string ClipState();
            void MouseOver();
            void MouseOut();
            void MouseClick();
            // focus |callback
            bool CallBack() { return _callback(); }
            virtual bool hasFocus() {}
            virtual void GetFocus() {}
            virtual void DelFocus() {}
            virtual void Animate() {}
            bool Focusable() { return _focusable; }
            bool isSprite() { return (!_focusable && (_callback == NULL)); }
            // gfx
            void Draw();
            // return widgets rect
            SDL_Rect* rect() { return _sandp; }
            string id() { return _id; }
     
            virtual ~Widget();
     
        protected:
            Widget() {};
            string _id;
            SDL_Surface* _sprite;
            SDL_Surface* _dest;
            SDL_Rect* _sandp;
            SpriteSheet* _ss;
            funcptr _callback;
            bool _focusable;
        private:
    };
    donc je me retrouve avec un constructeur, apparament illégal ?

  5. #5
    Membre actif Avatar de Rewpparo
    Homme Profil pro
    Amateur
    Inscrit en
    Décembre 2005
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Amateur

    Informations forums :
    Inscription : Décembre 2005
    Messages : 170
    Points : 281
    Points
    281
    Par défaut
    Si tu as plusieurs fichiers source dans ton projet, effaces les fichiers intermédiaires de compilation et recompiles a partir de rien (make clean && make)

Discussions similaires

  1. Réponses: 9
    Dernier message: 16/10/2006, 16h35
  2. prédicat pour min_element d'une std::map
    Par Kurisu dans le forum SL & STL
    Réponses: 6
    Dernier message: 11/09/2006, 19h27
  3. Vider une std::map de pointeur
    Par Zenol dans le forum SL & STL
    Réponses: 14
    Dernier message: 10/02/2006, 13h16
  4. std::map::find
    Par Blowih dans le forum SL & STL
    Réponses: 12
    Dernier message: 21/12/2005, 19h42
  5. Libérer des pointeurs dans une std::map
    Par GaldorSP dans le forum SL & STL
    Réponses: 2
    Dernier message: 09/07/2005, 14h42

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