Bonjour.
Je code en ce moment un petit programme avec Qt 4.6 (sous Windows 7 x64, Codeblocks et mingw gcc 4.5.0) et j'ai de multiple questions pour tenter d'éclaircir ma vision quant à la gestion de la mémoire par Qt.
Tout d'abord voici en gros mon programme de test :
J'ai une QMainWindow Fenetre1 très simple avec un widget central (vide pour le moment) et une menuBar. Dans cette menuBar, un clic sur l'un des menus doit ouvrir une nouvelle fenêtre Fenetre2 (type boîte de dialogue, mais éditée par moi et héritant directement d'un QWidget). Cette Fenetre2 regroupe plusieurs boutons ainsi qu'une animation .mng (QMovie) qui prend pas mal de place en mémoire. Je veux donc que quand l'on ferme cette Fenetre2, tout ce qui était en mémoire associé à celle-ci soit correctement effacé.
Concernant l'allocation en mémoire voici les différentes techniques utilisées pour les déclaration de variables (et j'aimerai des précisions là dessus) :
Technique 1 : Variable locale dans fonction membre
Question 1 : pouvez vous me confirmer qu'une fois que MaFonction a été exécutée, maVariable est effacée ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 void MaClasse::MaFonction() { QString maVariable; maVariable="Bonjour"; }
Technique 2 : Variable locale dans fonction membre par pointeur
Question 2 : là normalement, à chaque fois que la fonction est exécutée, un nouveau bouton est créé. Ils sont tous détruits quand MaClasse est détruite. C'est ça ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 void MaClasse::MaFonction() { QPushButton *monBouton=new QPushButton("Cliquez!",this); }
Question 3 : par contre si l'on ne met pas le parent "this", et que l'on met 0 à la place que se passe-t-il ? Chaque nouvel appel devrait créer un nouveau bouton mais quand MaClasse sera détruite, les boutons ne le seront pas...
Technique 3 : Variable membre
Question 4 : en principe là, monBouton est créé avec la classe et est détruit avec elle. Donc à priori pas trop de problème de mémoire. J'ai bon ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 private: QPushButton monBouton; ------------------------------------------------------------ void MaClasse::MaFonction() { monBouton.setText(Cliquez!); }
Technique 4 : Variable membre par pointeur
Question 5 : Alors là, j'ai un peu plus de mal. En principe MaFonction ne devra être appelée qu'une seule fois, et dans le constructeur. Que se passe-t-il si jamais MaFonction est exécutée plusieurs fois ? (donc plusieurs new pour le même objet)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 private: QPushButton *monBouton; ------------------------------------------------------------ void MaClasse::MaFonction() { monBouton=new QPushButton("Cliquez!",this); }
Question 6 : En principe, si le parent est défini comme "this", le bouton sera détruit lorsque MaClasse sera détruite, c'est ça ?
Question 7 : Et si le parent est défini comme 0 au lieu de this, que se passera-t-il lors de la destruction de la classe ?
Question 8 (plus générale) : Dans les codes Qt, en général, les objets dérivés de Q_OBJECT sont gérés avec les techniques 2 et 4, tandis que les autres (comme les QPixmap par exemple) avec les techniques 1 et 3. Or si je vois l'intérêt de la technique 2 pour construire plusieurs objets avec une même fonction, j'ai beaucoup plus de mal avec la technique 4 puisqu'en général les objets sont initialisés dans le constructeur (du coup la technique 3 serait plus sûre non ?).
Mon problème de mémoire :
Actuellement, ma Fenetre2 est déclarée avec la Technique 2 dans l'un des slot associé à ma menuBar de la Fenetre1. Sans mesure particulière sur la Fenetre2, à chaque fois qu'on la ferme (avec un slot close()), l'animation reste en mémoire, et un nouveau clic dans la menuBar créé une nouvelle fenêtre avec une nouvelle animation (problème de mémoire donc...).
Si, dans le constructeur de la Fenetre2, je met un setAttribute(Qt::WA_DeleteOnClose) ça va déjà beaucoup mieux mais j'ai toujours un petit doute. Les mesures de mémoire application avec le gestionnaire des tâches de Windows (je n'ai pas d'autre moyen) donne en effet (je lance et je ferme 5 fois la Fenetre2) :
Question 9 : Pourquoi à chaque lancement/fermeture de la Fenetre2, les valeurs ne sont jamais les mêmes ?Début = 0 K
Lancement application = 3180 K
Déroulement des menus de la menuBar = 5116 K
Lancement de la Fenetre2 - 1 = 79480 K
Fermeture de la Fenetre2 - 1 = 7136 K
Lancement de la Fenetre2 - 2 = 79452 K
Fermeture de la Fenetre2 - 2 = 7640 K
Lancement de la Fenetre2 - 3 = 79424 K
Fermeture de la Fenetre2 - 3 = 7864 K
Lancement de la Fenetre2 - 4 = 79796 K
Fermeture de la Fenetre2 - 4 = 7540 K
Lancement de la Fenetre2 - 5 = 79292 K
Fermeture de la Fenetre2 - 5 = 7648 K
...
Question 10 : Pourquoi à la fermeture la Fenetre2, on ne revient pas à 5116 K (Déroulement des menus de la menuBar) ?
Merci mille fois à ceux qui prendront le temps de me lire et trouveront le temps de me répondre
Merci.
Partager