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 :

Crash à l'appel d'une méthode.


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Crash à l'appel d'une méthode.
    Salut, je possède une classe Button, dans laquelle je défini un bouton, et quelques foncteurs pour appeler une méthode d'une interface lorsqu'on clique sur le bouton ce qui donne ceci ;

    Code cpp : 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
     
    Button::Button(math::Vec3f position, math::Vec3f size, const Font* font, sf::String t, RenderWindow& rw) :
                    rw(rw),
                    LightComponent(position, size, size * 0.5f,false) {
                    background = sf::Color::White;
                    text.setFont(*font);
                    text.setString(t);
                    text.setColor(sf::Color::Black);
                    text.setPosition(position);
                    text.setSize(size);
                    rect = RectangleShape(size);
                    rect.setOutlineThickness(5.f);
                    rect.setOutlineColor(sf::Color::Black);
                }
                void Button::clear() {
                    rect.setFillColor(background);
                }
                void Button::setTextSize(unsigned int size) {
                    text.setCharacterSize(size);
                }
                void Button::setTextColor(sf::Color color) {
                    text.setColor(color);
                }
                void Button::draw(RenderTarget& target, RenderStates states) {
                    rect.setPosition(getPosition());
                    target.draw(rect, states);
                    target.draw(text, states);
                }
                std::string Button::getText() {
                    return text.getString().toAnsiString();
                }
                bool Button::isMouseInButton() {
                    physic::BoundingBox bb = getGlobalBounds();
                    math::Vec2f mousePos = math::Vec2f(sf::Mouse::getPosition(rw).x, sf::Mouse::getPosition(rw).y);
                    if (bb.isPointInside(mousePos)) {
                        return true;
                    }
                    return false;
                }
                void Button::addActionListener (ActionListener *al) {
                    core::FastDelegate<bool> trigger(&Button::isMouseInButton, this);
                    core::FastDelegate<void> slot(&ActionListener::actionPerformed,al, this);
                    core::Action a (core::Action::EVENT_TYPE::MOUSE_BUTTON_PRESSED_ONCE, sf::Mouse::Left);
                    core::Command cmd(a, trigger, slot);
                    getListener().connect("CBUTTONCLICKED", cmd);
                }

    Cette classe hérite de LightComponent, et la classe LightComponent de la classe component, pour chaque gui on a la possibilité de la rendre in/visible et de dés/activer son contexte de gestion d'événements.

    J'ai aussi ajouter une méthode que l'on peut redéfinir lorsque l'on change la visibilité ou lorsque l'on change l'état du contexte de gestion d'événements propre à la gui :

    Code cpp : 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
     
     int Component::nbComponents = 0;
            void Component::setEventContextActivated(bool activateEventContext) {
                this->activateEventContext = activateEventContext;
                onEventContextActivated(activateEventContext);
            }
            bool Component::isEventContextActivated() {
                return activateEventContext;
            }
            void Component::setVisible (bool visible) {
                onVisibilityChanged(visible);
                this->visible = visible;
            }
            bool Component::isVisible() {
                return visible;
            }
            void Component::onVisibilityChanged(bool visible) {}
            void Component::onEventContextActivated(bool activate) {}

    Les méthodes onVisiblityChanged et onEventContextActivated sont virtuelle.

    Mais j'ai un crash, lors de l'appel à la méthode setVisible :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    void Pong::actionPerformed(gui::Button* button) {
        if (button == m_bPseudo) {
            std::string text = "CONNECT*"+m_taPseudo->getText();
            SymEncPacket packet;
            packet<<text;
            Network::sendTcpPacket(packet);
            std::string response = Network::waitForLastResponse("CONNECTED");
            std::vector<std::string> infos = split(response, "*");
            if (infos[0] == "NOTOK") {
                m_pseudoUsed->setVisible(true);
            } else {
                m_taPseudo->setVisible(false);
                m_bPseudo->setVisible(false);

    Ca crash à cette ligne-ci :

    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    m_bPseudo->setVisible(false);

    Lors de l'appel de la méthode onVisibilityChanged.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #0 0xfffffffffffffff8	?? () (??:??)
    #1 0x45ee46	odfaeg::graphic::Component::setVisible(bool) () (??:??)
    #2 0x43d96f	Pong::actionPerformed(this=0x7fffffffe260, button=0x8a7730) (/home/laurent/Développement/Projets-c++/ODFAEGVIDEOTUTORIAL2/pong.cpp:149)
    #3 0x46534d	std::_Function_handler<void (odfaeg::graphic::gui::ActionListener*&, odfaeg::graphic::gui::Button*&), odfaeg::core::DynamicWrapper<void, odfaeg::graphic::gui::ActionListener, odfaeg::graphic::gui::Button*> >::_M_invoke(std::_Any_data const&, odfaeg::graphic::gui::ActionListener*&, odfaeg::graphic::gui::Button*&) () (??:??)
    #4 0x43584b	odfaeg::core::Listener::processEvents(this=0x8a7930) (/usr/local/include/odfaeg/Core/listener.h:161)
    #5 0x435755	odfaeg::core::Listener::pushEvent(this=0x8a7930, event=...) (/usr/local/include/odfaeg/Core/listener.h:142)
    #6 0x435973	odfaeg::graphic::Component::pushEvent(this=0x8a7730, event=...) (/usr/local/include/odfaeg/Graphics/component.h:19)
    #7 0x436182	odfaeg::core::Application::update(this=0x7fffffffe260) (/usr/local/include/odfaeg/Core/application.h:158)
    #8 0x435c67	odfaeg::core::Application::exec(this=0x7fffffffe260) (/usr/local/include/odfaeg/Core/application.h:77)
    #9 0x435444	main(argc=0x1, argv=-7048) (/home/laurent/Développement/Projets-c++/ODFAEGVIDEOTUTORIAL2/main.cpp:4)
    Bon, je ne comprends vraiment pas en quoi cela peut faire crasher. D'autant plus que je ne fais que de passer une instance d'une classe dérivant de l'interface et l'instance du bouton au foncteur, et ensuite, je récupère le pointeur sur le bouton qui a été cliqué lors de la redéfinition de la méthode virtuelle pure de l'interface. (comme en java)

    Et lorsque je veux rendre un bouton invisible dans cette méthode, ça crash. :/

  2. #2
    Invité
    Invité(e)
    Par défaut
    En résumé, le crash survient quand j'appelle une méthode virtuelle dans une méthode d'un objet passé à un foncteur.

    Sinon, pas de soucis si je met ça en commentaire :

    Code cpp : 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
     
    void Pong::actionPerformed(gui::Button* button) {
        if (button == m_bPseudo) {
            std::string text = "CONNECT*"+m_taPseudo->getText();
            SymEncPacket packet;
            packet<<text;
            Network::sendTcpPacket(packet);
            std::string response = Network::waitForLastResponse("CONNECTED");
            std::vector<std::string> infos = split(response, "*");
            if (infos[0] == "NOTOK") {
                m_pseudoUsed->setVisible(true);
            } else {
                m_taPseudo->setVisible(false);
                //button->setVisible(false);
                m_taPseudo->setEventContextActivated(false);
                //button->setEventContextActivated(false);

  3. #3
    Invité de passage

    Profil pro
    Inscrit en
    Décembre 2013
    Messages
    400
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 400
    Par défaut
    Si onVisiblityChanged n'est pas définie, le problème vient probablement pas de la fonction setVisibility. Du coup, c'est probablement un UB, qui fait crasher le programme n'importe où, mais surtout pas au bon endroit

    Difficile d'aider sans avoir un code minimal qui reproduit l'erreur et sans se pencher sur tout le code en détail (c'est probablement un heisenbug, donc le truc super chia... a identifier. Ou pas, c'est une pure question de chance)

    C'est typiquement le genre de problème que l'on a avec des pointeurs nus valide. La meilleurs solution : évite les pointeurs nus (pointeurs intelligents), vérifie des condition avec des assert (avant chaque utilisation d'un pointeur)

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 753
    Par défaut
    Si ton code compile mais que les variables button et m_bPseudo plantent à l'appel d'une méthode (ou d'un attribut), cela sent le pointeur supprimé mais pas initialisé à NULL après coup.

    D'autant que button == m_bPseudo

  5. #5
    Invité
    Invité(e)
    Par défaut
    Si onVisiblityChanged n'est pas définie, le problème vient probablement pas de la fonction setVisibility. Du coup, c'est probablement un UB, qui fait crasher le programme n'importe où, mais surtout pas au bon endroit
    onVisibilityChanged est définie...

    Si ton code compile mais que les variables button et m_bPseudo plantent à l'appel d'une méthode (ou d'un attribut), cela sent le pointeur supprimé mais pas initialisé à NULL après coup.

    D'autant que button == m_bPseudo
    Oui, je compare les adresses des boutons pour savoir sur quel bouton on a cliqué.

    Et les pointeurs, ne sont pas supprimé, mon framework gère la mémoire de manière intelligente c'est à dire que j'ajoute mes guis dans un cache, et, les pointeurs sont détruit à la destruction du cache. (c'est à dire tout à la fin de l'application)

    Exactement comme avec le framework Qt.

    Je sens que ce crash va être difficile à déboguer, je vais essayer avec un code plus minimal.

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 753
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 753
    Par défaut
    Citation Envoyé par Lolilolight Voir le message
    Oui, je compare les adresses des boutons pour savoir sur quel bouton on a cliqué.
    Tu n'as pas compris ce que je voulais dire : tu as un plantage sur le MÊME objet et non pas sur 2 objets distincts.

    Citation Envoyé par Lolilolight Voir le message
    Et les pointeurs, ne sont pas supprimé, mon framework gère la mémoire de manière intelligente c'est à dire que j'ajoute mes guis dans un cache, et, les pointeurs sont détruit à la destruction du cache. (c'est à dire tout à la fin de l'application)
    Que ton objet soit auto-géré, géré à la main, mis en cache, mis dans un bassin, ou je ne sais pas quoi, cette ligne est explicite
    odfaeg::graphic::Component::setVisible(bool) () (??:??).

    Ton pointeur est crasseux qu'il soit détruit, slicé, mal réinterprété ou je ne sais pas quoi

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

Discussions similaires

  1. Appel d'une méthode virtuelles
    Par BIPBIP59 dans le forum C++Builder
    Réponses: 4
    Dernier message: 24/03/2006, 14h00
  2. Réponses: 2
    Dernier message: 29/12/2005, 10h25
  3. Réponses: 2
    Dernier message: 06/12/2005, 09h41
  4. Réponses: 6
    Dernier message: 27/05/2005, 15h43
  5. Comment connaitre l'appelant d'une méthode
    Par Alec6 dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 12/07/2004, 14h51

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