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

Qt Discussion :

Gestion de la mémoire


Sujet :

Qt

  1. #1
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    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
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    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 confirmé Avatar de saad.hessane
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    315
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    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 : 496
    Points
    496
    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
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    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
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

Discussions similaires

  1. Réponses: 17
    Dernier message: 02/02/2006, 12h03
  2. gestion de la mémoire
    Par moldavi dans le forum C++
    Réponses: 17
    Dernier message: 04/02/2005, 23h18
  3. Réponses: 11
    Dernier message: 26/12/2004, 22h50
  4. Gestion de la mémoire entre plusieurs DLL
    Par Laurent Gomila dans le forum C++
    Réponses: 7
    Dernier message: 27/07/2004, 15h28
  5. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44

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