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 :

Bug Qt ? classe QTreeWidgetItem


Sujet :

Qt

Vue hybride

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Par défaut Bug Qt ? classe QTreeWidgetItem
    Slt, j'ai toujours du mal à y croire mais je crois avoir trouvé deux bugs dans la bibliothèque de Qt.... Je suis avec la version 4.5 de Qt, la dernière à ce jour. Ce bug concerne la classe QTreeWidgetItem

    Il semblerait que si je crée un objet de ce type, que je fais une boucle pour lui ajouter énormément de fils (assez pour voir une utilisation de la RAM augmenter) et que je fasse un delete de cet objet, Qt ne libére pas la mémoire de tous ses fils... Il appelle bien le delete sur tous ses fils mais la mémoire n'est pas libérée... Je me suis fait une petite classe test qui peut avoir des fils un peu dans le même genre et dans le destructeur, je détruis tous les fils et là, toute la mémoire est bien libérée. Pourquoi pas avec le QTreeWidgetItem ? Le problème vient de moi ou de Qt ?

    Exemple de code, surveillez votre utilisation de la RAM :

    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
     
    #include <QApplication>
    #include <QTreeWidgetItem>
     
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QTreeWidgetItem * Root = new QTreeWidgetItem(&w);
     
        for(int i = 0; i < 10000; ++i)
        {
            Root->addChild(new QTreeWidgetItem());
            for(int j = 0; j < 30; ++j)
                Root->child(i)->addChild(new QTreeWidgetItem(Root));
        }
     
        qDebug("Debut sleep ");// Utilisation forte de la memoire
        sleep(5);
        qDebug("Fin sleep, debut delete");
        delete Root;
        qDebug("Fin delete");// devrait avoir une utilisation de la ram
    // d'environ 3Mo... Mais ce n'es pas le cas...
     
        sleep(10000000);
        return a.exec();
    }
    J'ai créé une classe qui dérive de QTreeWidgetItem et j'ai mis un débug dans le destructeur et le destructeur de tous les fils est bien appelé... Pourquoi cette mémoire n'est donc pas libérée ?

    Merci d'avance pour vos réponses !
    Cordialement.

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Salut,

    Je pense que tu confonds la parenté entre un widget et ses widgets fils, et la parenté dans un arbre.


    Relis la doc, mais tu verras que la destruction d'un noeud dans l'arbre n'entraine pas la destruction des branches/noeuds qui lui étaient accrochés. Et heureusement !

    Donc il est normal que tes items ne soient effectivement pas détruits.

    G.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Par défaut
    Tout d'abord, merci pour la réponse.

    Je comprends bien la distinction entre ces deux parentés mais justement, les deux se confondent. J'ai justement eut un gros problème en essayant d'insérer un élément au milieu des fils et non à la fin. Il est possible d'insérer un fils à un noeud à l'indice que l'on veut grâce à la méthode void insertChild ( int index, QTreeWidgetItem * child ). Pour ajouter un fils je faisais donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    // Pour créer le fils avec comme parent Root
    QTreeWidgetItem * Nouveau = new QTreeWidgetItem(Root);
    // Puis je l'ajoutais dans l'ARBRE
    Root->insertChild(n, Nouveau);
    Et avec ce code, il ne me l'insère pas à l'indice n mais à la fin... Car justement en lui définissant un père, il s'ajoute automatiquement à celui-ci.

    De plus, si il ne supprime pas tous les fils, pourquoi dans ce cas appelle-t-il les destructeurs de tous ses fils et sous-fils ?

    Pour le savoir, j'ai fait ma classe qui héritait de QTreeWidgetItem et j'ai mis un élément de débug qui affiche dans la console "destruction d'un fils". Donc s'il ne supprimait que la racine, je devrait n'avoir qu'une seule ligne et là, j'en ai autant que de fils...

    Il appelle donc bien le destructeur de tous les fils et l'intégralité de la mémoire devrait être libérée.

    De plus, dans mon héritage de la classe, j'ai également ajouté dans le destructeur un parcours de tous les fils pour les deleter. Là, c'est donc fait manuellement, c'est donc obligé qu'il les supprime. Hé ben non, toujours la même chose...

    Pourquoi, je n'arrive vraiment pas à comprendre. Peut-être y-a-t-il quelque chose que je n'ai pas bien compris mais là, j'ai du mal.

    Merci d'avance.
    Cordialement.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Je m'éloigne un peu du sujet, mais as tu un but précis ? Ou tu cherches juste à tester la chose ?

    Car si je me rappelle bien, il me semble que c'est à la destruction de l'arbre (le QTreeWidget) que les items sont détruits, et non à la destruction du noeud père.

    Ensuite, pour la libération mémoire non effective, il y a plusieurs possibilités :
    -comme tu l'a dis, le destructeur des items est appelé, c'est pas pour autant que la destruction est faite. Il peut y avoir un test dans le destructeur qui annule la destruction si celle-ci risque d'entraîner des problèmes.
    -je ne sais pas quel OS tu utilises, mais la mémoire est rarement libérée dès l'appel au delete, il peut se faire un peu plus tard, ou à la fermeture de l'application, voire même après.

    Voici une doc autre que celle de la classe, pour utiliser les qtreewidget.

    G.

    PS : Perso, j'ai pas testé, mais ça m'étonnerait qu'il y ait un bug, car c'est une partie du framework déjà bien éprouvée. A mon avis, c'est juste une mauvaise utilisation des QtreeWidgetItems.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 214
    Par défaut
    Mon but est d'éviter des fuites de mémoires lors de multiples ajouts/suppressions des noeuds...

    Mon OS est Ubuntu et j'ai fait une classe de test qui représente une arborescence et la mémoire est libérée à la fin des delete (quand mon code affiche fin delete).

    L'arbre ne sera détruit qu'à la fin de l'application donc ça ne m'intéresse pas.

    Dans mon exemple, je n'utilise pas de QTreeWidget, donc comment serait-ce possible ?

    En tout cas, je trouve ça fou que quand je fais un delete d'un objet, il ne soit pas supprimé...

    Merci d'avance.

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mai 2007
    Messages
    774
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Mai 2007
    Messages : 774
    Par défaut
    Si tu veux créer un arbre sans forcément le représenter, utilise les model (QAbstractItemModel, QStandardItemModel, etc...). Ces classes sont beaucoup plus flexibles et puissantes. Et là, la destruction du modèle entraîne la destruction des items. De même, la destruction d'un item détruit ses items fils.

    Les QTreeWidgets / QTreeWidgetItems servent uniquement à créer et afficher *simplement* un arbre.

    G.

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

Discussions similaires

  1. [Objective-C] bug avec class NSDictionnary, methode bug
    Par manonthemoon dans le forum Objective-C
    Réponses: 1
    Dernier message: 21/09/2012, 10h53
  2. Bug sur class LyPasswordBehavior
    Par zdidier dans le forum W4 Express
    Réponses: 1
    Dernier message: 14/04/2009, 11h51
  3. Bug TabbedTextOut() (classe CDC)
    Par sebas26100 dans le forum Visual C++
    Réponses: 0
    Dernier message: 25/11/2008, 11h14
  4. Utilisation de setTimeout avec des classes : BUG!
    Par seb-oulba dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 01/09/2006, 09h43
  5. [FLASH 8 ] bug compilation avec class
    Par CR_Gio dans le forum Flash
    Réponses: 6
    Dernier message: 31/05/2006, 20h55

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