Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2012
    Messages
    679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2012
    Messages : 679
    Points : 1 297
    Points
    1 297

    Par défaut Gestion de la mémoire

    Hello,

    J'ai une fenêtre contenant entre autre un Widget perso (dérivé de QWidget).
    Ce widget perso est créé dans du code auto généré, et devrait être supprimé lorsque la fenêtre est supprimée (car la fenêtre est son parent).

    Sauf que ce widget n'est jamais supprimé. Du coup c'est fiable ce système de suppression des widgets fils ? Ou il faut tout supprimer à la main (au risque de se taper des heap corruptions si un objet est delete plusieurs fois) ?

    Et deuxième question, si les signaux / slots de 2 widgets sont connectés, puis qu'un des deux widgets est supprimé, se prendre un seg fault au niveau de l'emit est normal ? Il faut les déconnecter à la main avant la suppression ?

    (c'est d'ailleurs à cause grace à un seg fault sur un emit que je me suis rendu compte que mon widget perso n'est pas supprimé, ça aurait du planter avant ^^)

  2. #2
    Modérateur
    Avatar de koala01
    Profil pro Philippe Dunski
    Inscrit en
    octobre 2004
    Messages
    9 661
    Détails du profil
    Informations personnelles :
    Nom : Philippe Dunski
    Âge : 42

    Informations forums :
    Inscription : octobre 2004
    Messages : 9 661
    Points : 15 972
    Points
    15 972

    Par défaut

    Salut,

    Si le parent de ton widget perso est correctement défini, oui, le système s'occupera de tout.

    N'oublie cependant pas que la fermeture de ta fenêtre ne signifie pas forcément la destruction de celle-ci, car elle peut etre réouverte sans avoir été recréer

    Le tout dépend au final de comment tu crées le widget parent de ton widget perso

    Pour ta deuxième question, cela dépend fortement du widget qui est détruit...

    Si le widget détruit est celui qui émet le signal, il n'y a strictement aucun problème : le signal n'étant plus émis, il ne risque pas d'être envoyé à quelque chose qui n'existe plus

    Si le widget détruit est celui dont un slot est connecté, alors, effectivement, il faut veiller à le déconnecter du signal dans l'autre widget pour éviter les problèmes

    Si chacun des widget émet un signal en direction d'un slot de l'autre widget, il est peut etre intéressant de revoir ton desing
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  3. #3
    Membre éprouvé Avatar de saad.hessane
    Homme Profil pro Saâd Hessane
    Ingénieur développement logiciels
    Inscrit en
    avril 2008
    Messages
    315
    Détails du profil
    Informations personnelles :
    Nom : Homme Saâd Hessane
    Âge : 25
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : avril 2008
    Messages : 315
    Points : 490
    Points
    490

    Par défaut

    Citation Envoyé par Iradrille Voir le message
    [...]Du coup c'est fiable ce système de suppression des widgets fils ? Ou il faut tout supprimer à la main (au risque de se taper des heap corruptions si un objet est delete plusieurs fois) ?
    Oui c'est fiable.
    Si tu détruis le parent, tous les objets fils seront détruit. Si tu détruis un fils, il émet le signal destroyed auquel est connecté le parent pour qu'il le supprime de sa liste d'enfants. Plus de détail : http://qt-project.org/doc/qt-4.8/objecttrees.html


    Citation Envoyé par Iradrille Voir le message
    Et deuxième question, si les signaux / slots de 2 widgets sont connectés, puis qu'un des deux widgets est supprimé, se prendre un seg fault au niveau de l'emit est normal ? Il faut les déconnecter à la main avant la suppression ?

    (c'est d'ailleurs à cause grace à un seg fault sur un emit que je me suis rendu compte que mon widget perso n'est pas supprimé, ça aurait du planter avant ^^)
    Normalement à la destruction de l'objet, toutes les connections avec cet objet sont détruites ( signaux et slot, et donc connections avec récepteurs et émetteurs ).
    Peux-tu poster un code ?

    [EDIT] @koala01 : Je n'ai remarqué ta réponse qu'après avoir poster
    Citation Envoyé par koala01 Voir le message
    Si le widget détruit est celui dont un slot est connecté, alors, effectivement, il faut veiller à le déconnecter du signal dans l'autre widget pour éviter les problèmes
    Je ne pense pas que ça soit le cas. Les connections faisant intervenir l'objet détruit doivent normalement être coupées. C'est ce que la doc dit d'ailleurs.
    Citation Envoyé par Doc Qt
    QObject::~QObject () [virtual]
    Destroys the object, deleting all its child objects.
    All signals to and from the object are automatically disconnected, and any pending posted events for the object are removed from the event queue. However, it is often safer to use deleteLater() rather than deleting a QObject subclass directly.

  4. #4
    Modérateur
    Avatar de koala01
    Profil pro Philippe Dunski
    Inscrit en
    octobre 2004
    Messages
    9 661
    Détails du profil
    Informations personnelles :
    Nom : Philippe Dunski
    Âge : 42

    Informations forums :
    Inscription : octobre 2004
    Messages : 9 661
    Points : 15 972
    Points
    15 972

    Par défaut

    Citation Envoyé par saad.hessane Voir le message
    [EDIT] @koala01 : Je n'ai remarqué ta réponse qu'après avoir poster

    Je ne pense pas que ça soit le cas. Les connections faisant intervenir l'objet détruit doivent normalement être coupées. C'est ce que la doc dit d'ailleurs.
    Je peux t'assurer, pour avoir du gérer le problème plus d'une fois, que c'est pas si évident que cela, du moins jusqu'à la version 4.7...

    Bon, c'étaient des cas limites, mais, quand tu as une vue tabulaires dont certains signaux sont connectés sur des QGraphicsItems qui se trouvent dans une vue tout à fait différente, et que, de l'autre coté tu as des QGraphicsItems qui sont connectés à des slots de ta vue tabulaire, même la version 4.7 a tendance à perdre un peu les pédales lorsque tu détruit une vue mais pas l'autre
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  5. #5
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2012
    Messages
    679
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2012
    Messages : 679
    Points : 1 297
    Points
    1 297

    Par défaut

    Après avoir regardé plus en détail mon code, l'erreur était vraiment conne :/

    La fenêtre détruit bien le widget custom (vérifié avec des cout dans les destructeurs) mais le widget reste "plus ou moins" valide.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class MonWidget: QWidget {
      ....
     
      void test() {
         std::cout << "test\n";
         emit unSignal();
      }
    };
     
    delete monWidget; // exécuté par Qt à la destruction de la fenêtre
    monWidget->test();
    Apres destruction, test() s'exécute "correctement" sans l'emit et me lance un seg fault avec.

    Bon utiliser un objet détruit est clairement une erreur... mais comme la fonction s'exécutait normalement sans l'emit je ne pensais pas l'objet détruit.

    Bref une erreur stupide, merci pour les précisions sur le mécanisme de suppression des widgets.

    edit: Le fait que l'objet est valide après sa destruction doit venir du contexte multithread, il doit rester en cache quelques part je pense, m'enfin design changé, plus de problèmes.

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •