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

Discussion :

Erreur de segmentation et signal aboutToQuit

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut Erreur de segmentation et signal aboutToQuit
    Bonjour,

    J'ai un segmentation fault à l'appel de la méthode quit() de mon QApplication personnalisé.
    Voici un exemple minimaliste qui le reproduit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int main(int argc, char *argv[])
    {
      CApplication a(argc, argv);
      return a.exec();
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CApplication::CApplication(int& argc, char** argv) :
        QApplication(argc, argv)
    {
      pModule = new Module(this); // QApplication est parent du module
    }
    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
    Module::Module(QObject *parent) :
        QObject(parent)
    {
      w = new MainWindow();
      w->show();
    }
     
    Module::~Module()
    {
      if (w)
      {
        delete w; // Seg fault ici
        w = NULL;
      }
    }
    Voici la pile :
    0 Module::~Module module.cpp 13 0x4024dd
    1 Module::~Module module.cpp 18 0x402565
    2 QObjectPrivate::deleteChildren qobject.cpp 1841 0x6b942187
    3 QObject::~QObject qobject.cpp 934 0x6b940b49
    4 QCoreApplication::~QCoreApplication qcoreapplication.cpp 754 0x6b91b7c5
    5 QGuiApplication::~QGuiApplication qguiapplication.cpp 499 0x2108c6d
    6 QApplication::~QApplication qapplication.cpp 685 0x9996797
    7 CApplication::~CApplication capplication.h 8 0x409332
    8 qMain main.cpp 6 0x401625
    9 WinMain@16 qtmain_win.cpp 131 0x403e7d
    10 main 0x40a5fd
    J'ai trouvé une solution qui consiste à appeler un méthode pour détruire le module sur un signal aboutToQuit() de l'application :
    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
    CApplication::CApplication(int& argc, char** argv) :
        QApplication(argc, argv)
    {
      pModule = new Module(this);
     
      QObject::connect(this, SIGNAL(aboutToQuit()),
                       this, SLOT(clean()));
    }
     
    void CApplication::clean()
    {
      if (pModule)
      {
        delete pModule;
        pModule = NULL;
      }
    }
    Ce qui m'ennuie, c'est que je ne sais pas bien l'expliquer..

    Une idée ? :-)

    Merci!

  2. #2
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    Bonjour.

    La gestion de la durée de vie des objets est différente en C++/Qt du C++ natif.
    Il faut savoir que les classes qui héritent de QObject (QMainWindow, QApplication et Module) sont détruites automatiquement lorsque leur parent est détruit, à condition que chaque objet connaisse son parent (avec setParent()) ou quand il est construit.

    On ne doit jamais appeler delete sur elles.
    Ce que tu essaie de faire, détruire chaque pointeur lors de la destruction, est typiquement ce que Qt fait automatiquement.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Salut manudiclemente :-)

    Il faut savoir que les classes qui héritent de QObject (QMainWindow, QApplication et Module) sont détruites automatiquement lorsque leur parent est détruit, à condition que chaque objet connaisse son parent (avec setParent()) ou quand il est construit.
    Oui bien sûr, mais la fenêtre principale, mère de tous les composants, n'aura pas de parent.
    Elle ne peut d'ailleurs pas avoir pour parent un type QObject qui n'est pas graphique.
    D'où l'utilisation d'un delete dans ce cas précis (dans le cas d'une gestion dynamique de la mémoire).

    Ce que tu essaie de faire, détruire chaque pointeur lors de la destruction, est typiquement ce que Qt fait automatiquement. .
    Encore une fois, je le fais juste pour la fenêtre principale.
    Je vais faire le test mais je dirais comme ça que, même si on fait un delete sur un objet graphique qui a un parent, Qt teste le pointeur au moment de détruire les enfants de l'objet graphique parent. Il n'y aurait donc peut être même pas de crash.

    Je pense que le problème est ailleurs, lié peut être à la boucle des événements, à la gestion de QGuiApplication.

  4. #4
    Membre émérite
    Avatar de Daïmanu
    Homme Profil pro
    Développeur touche à tout
    Inscrit en
    Janvier 2011
    Messages
    736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur touche à tout

    Informations forums :
    Inscription : Janvier 2011
    Messages : 736
    Par défaut
    En effet, j'ai lu trop vite et je n'ai pas vu le problème .

    J'ai recopié le code que tu as fourni, il fonctionne chez moi.

    0 Module::~Module module.cpp 13 0x4024dd
    1 Module::~Module module.cpp 18 0x402565
    J'ai l'impression que tu a créé deux modules, peut-être le bug vient de cette classe ?

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

    Ne deleterais-tu pas aussi pModule dans le destructeur de CApplication ? Tu sembles vouloir justement le libérer dans ton second essai...
    Si oui, l'erreur vient bien que là car comme te l'a expliqué manudiclemente, en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pModule = new Module(this);
    dans le constructeur de CApplication, tu donnes la responsabilité à ta classe d'effectuer la libération de ce pointeur. Donc si tu le libères aussi de ton côté, on arrive irrémédiablement à un plantage dû à un double delete.

    Voir ce sujet de la FAQ pour en savoir plus

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2012
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2012
    Messages : 99
    Par défaut
    Salut et merci à tous les deux

    J'ai l'impression que tu a créé deux modules, peut-être le bug vient de cette classe ?
    Je n'ai rien fait de plus que d'instancier dynamiquement le module dans CApplication donc il n'y a pas de raison normalement.
    C'est vrai que le double appel du destructeur dans la pile est un peu étrange par contre.

    J'ai recopié le code que tu as fourni, il fonctionne chez moi.
    Tu as bien commenté la connection pour empêcher l'appel à la méthode clean() ?

    Ne deleterais-tu pas aussi pModule dans le destructeur de CApplication ? Tu sembles vouloir justement le libérer dans ton second essai...
    Tout d'abord, pour la solution apportée avec le delete du module ajouté dans le slot clean() appelé sur signal aboutToQuit(), il n'y a pas de crash.
    Qt doit gérer correctement lors de la destruction les pointeurs des enfants déjà NULL pour éviter le problème du double delete apparemment.

    Ci-joint un projet minimaliste qui, chez moi, crash à tous les coups au moment de quitter l'application dans le menu principal.

    Quelque chose doit m'échapper encore
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. Erreur de segmentation Vim Signal mortel SEGV
    Par Leaffy dans le forum Applications et environnements graphiques
    Réponses: 5
    Dernier message: 16/08/2012, 08h58
  2. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  3. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  4. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18
  5. erreur ora-12801 : error signaled in parallel query server
    Par dngaya dans le forum Administration
    Réponses: 5
    Dernier message: 15/04/2004, 16h25

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