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 :

[QTreeView] Fuite mémoire avec setModel() ?

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 10
    Par défaut [QTreeView] Fuite mémoire avec setModel() ?
    Bonjour,

    J'ai développé une application inspirée de l'exemple "simpletreemodel".

    Observée depuis le gestionnaire de tâches, cette application, en termes de mémoire, fuit.

    La différence principale, relativement à l'exemple cité, est que les appels à la fonction membre "setModel(...) " de QTreeView sont récurrents.

    J'ai donc repris l'exemple "simpletreemodel" et ai modifié le fichier "main.cpp" afin de mettre en évidence le problème évoqué.

    En voici le code:

    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include <QtGui>
    
    #include "treemodel.h"
    
    TreeModel * model = 0;
    QTreeView * view = 0;
    
    class QObject;
    class QEvent;
    
    class Application : public QApplication
    {
    private:
      int m_timerId;
    
    public:
      Application(int argc, char * argv[]);
    
      bool notify(QObject * receiver, QEvent * event);
    
      void timerId(int value);
    
     void timerEvent(QTimerEvent * event);
    };
    
    Application::Application(int argc, char * argv[])
    : QApplication(argc, argv)
    {
      connect(this, SIGNAL(destroyed()), this, SLOT(quit()));
    }
    
    bool Application::notify(QObject * receiver, QEvent * event)
    {
      if (receiver == this)
      {
        if (event->type() == QEvent::Quit)
        {
          if (model)
            delete model;
          if (view)
            delete view;
        }
    
        if (event->type() == QEvent::Timer)
          killTimer(m_timerId);
      }
    
      return QApplication::notify(receiver, event);
    }
    
    void Application::timerId(int value)
    {
      m_timerId = value;
    }
    
    void Application::timerEvent(QTimerEvent * event)
    {
      if (view)
      {
        if (model)
          delete model;
    
        QFile file(":/default.txt");
        file.open(QIODevice::ReadOnly);
        model = new TreeModel(file.readAll());
        file.close();
    
        view->setModel(model);
        view->show();
      }
    }
    
    int main(int argc, char *argv[])
    {
      Q_INIT_RESOURCE(simpletreemodel);
    
      Application app(argc, argv);
    
      QFile file(":/default.txt");
      file.open(QIODevice::ReadOnly);
      model = new TreeModel(file.readAll());
      file.close();
    
      view = new QTreeView();
      view->setWindowTitle(QObject::tr("Simple Tree Model"));
    
      app.startTimer(100);
    
      view->setModel(model);
      view->show();
    
      return app.exec();
    }
    La ligne en cause est en rouge.

    Il suffit de mettre cette ligne en commentaire pour que l'application ne "fuit" plus.

    Auriez-vous une explication ?
    Voire une solution que me permettrait d'actualiser la vue en évitant cet écueil.

    Merci d'avance.

    Cordialement.

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 10
    Par défaut Bug reporté sur JIRA Qt Nokia
    Bonjour,

    Comme moi, vous séchez.

    J'ai reporté le bug sur JIRA Qt Nokia.

    Classifié comme bug important.

    Je vous informerai de leur réponse.

    Dans le doute, à ceux qui utilisent QtTreeView, soyez prudent.

    Cordialement.

  3. #3
    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 t'emballes un tout petit peu. Déjà, il ne faut pas trop compter sur la précision du gestionnaire de tâches de Windows en ce qui concerne la gestion de mémoire en temps réel.

    Cependant, tu as raison, il est probable que la façon dont tu utilises la méthode setModel entraîne une fuite mémoire. As tu bien lu la doc ?
    void QAbstractItemView::setModel ( QAbstractItemModel * model ) [virtual]

    Sets the model for the view to present.

    This function will create and set a new selection model, replacing any model that was previously set with setSelectionModel(). However, the old selection model will not be deleted as it may be shared between several views. We recommend that you delete the old selection model if it is no longer required. This is done with the following code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    QItemSelectionModel *m = view->selectionModel();
     view->setModel(new model);
     delete m;
    If both the old model and the old selection model do not have parents, or if their parents are long-lived objects, it may be preferable to call their deleteLater() functions to explicitly delete them.

    The view does not take ownership of the model unless it is the model's parent object because the view may be shared between many different views.

    See also model(), selectionModel(), and setSelectionModel().
    En gros, ce qui est dit, c'est qu'il faut supprimer l'ancien selection model après avoir fait un setModel(). Hors, dans ton exemple, tu ne le fais pas.

    G.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 10
    Par défaut
    Gulish,

    Afin de vous répondre point par point.

    Je ne m'emballe pas du tout.
    Le gestionnaire de tâches de Windows est précis eu égard à l'utilisation que j'en fais et relativement au problème qui se pose à moi, c'est-à-dire de mettre en évidence que mes applications ne fuient pas après plusieurs heures de fonctionnement.

    Il n'est donc pas probable mais sûr que les appels récurrents à "setModel(...) crée une fuite mémoire.

    Quant à savoir si j'ai lu la documentation ... bien évidemment, c'est le minimum lorsqu'on développe sur la base d'une classe fournie dans le cadre d'un frame work.
    Quant à savoir si j'ai appliqué la solution que vous me suggérez, bien sûr, je l'ai fait, sans succès.

    Mais malgré celà, j'aurais pu me fourvoyer.
    Alors, sans vous commander, sur l'exemple que je suggère, pourriez vous faire l'essai de supprimer l'ancien model avant d'en appliquer un nouveau ?

    S'il se vérifiait que c'est la solution, vous pourriez en informer la personne de chez Qt, chevronnée aussi, qui se casse la tête sur ce problème qu'elle a qualifié de bug de priorité importante.

    Bien cordialement.

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 10
    Par défaut Bug suivi par JIRA Qt Nokia
    A tous,

    Je n'ai pas de retour d'information relativement à ce bug.

    Cela, bien évidemment hypothèque lourdement la recette de mon applicatif.

    Pour ceux qui serait en attente, voici le lien succeptible de fournir, à terme, une solution.

    http://bugreports.qt.nokia.com/browse/QTBUG-11508

    Bien cordialement.

Discussions similaires

  1. Détection de fuites mémoire avec Valgrind
    Par dj.motte dans le forum GTK+ avec C & C++
    Réponses: 25
    Dernier message: 22/11/2008, 08h49
  2. Fuite mémoire avec code externe
    Par samW7 dans le forum C++
    Réponses: 8
    Dernier message: 01/02/2008, 02h33
  3. [AJAX] Appolo 13 - Fuite mémoire avec XHR
    Par mecatroid dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/09/2007, 14h52
  4. Fuites mémoires avec Vector
    Par ..alex.. dans le forum SL & STL
    Réponses: 15
    Dernier message: 10/08/2006, 11h35
  5. Fuite mémoire avec valgrind
    Par franchouze dans le forum C++
    Réponses: 3
    Dernier message: 05/06/2006, 16h47

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