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

C++ Discussion :

Singleton et Fuite mémoire avec objet STL


Sujet :

C++

  1. #1
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut Singleton et Fuite mémoire avec objet STL
    Bonjour à tous,

    J'ai un petit souci dans mon application j'ai recours à l'utilisation de singleton et d'objet de la STL et tout ça sous VISUAL c++ 2010 Express donc vous l'aurez compris sous environnement windows.

    Suit à plusieurs fuite de mémoire dans mon application, j'ai pu tester le bout de code test suivant :
    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
     
     
    #include <vector>
    // Windows memory leak checking
     
    #ifdef _DEGUB
    #define _CRTDBG_MAP_ALLOC
    #include <stdlib.h>
    #include <crtdbg.h>
    #define new new(_NORMAL_BLOCK, __FILE__, __LINE__)
    #endif
     
    //classe de singleton test
    class A
    {
    	private:
    		A(){};
    		~A(){};
     
    		std::vector<int> tab;
    	public:
    		static A &Instance()
    		{
    			static A objetA;
    			return objetA;
    		}
    };
     
     
    void main()
    {
     
     
    	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
     
    	A::Instance();
     
    	_CrtDumpMemoryLeaks();
    }
    Après exécution de ce bout de code tout simple il me marque qu'il y a des fuites de mémoire :
    Detected memory leaks!
    Dumping objects ->
    {131} normal block at 0x003460A0, 8 bytes long.
    Data: <HTB > 48 54 42 00 00 00 00 00
    Object dump complete.
    Le programme '[4060] test.exe: Natif' s'est arrêté avec le code 0 (0x0).
    J'ai repris le même code avec un simple tableau à la place d'un std::vector et je n'ai plus d'après de débugger de fuite de mémoire.

    Voilà donc c'est bien dommage si je ne peux pas utiliser les structures de la stl avec mes singletons.

    Quelqu'un pourra peut-être me dire où je fais une erreur dans l'emploie de mon singleton ? ou si c'est un faux positif de fuite de mémoire ? ou tout autre explication.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Tu n'as pas de fuite mémoire. L'objet statique créé dans le singleton est détruit lorsque les destructeurs sont collectés, après la sortie de main() - hors tu affiches l'état de la mémoire avant la sortie de main().

    Tu peux donc le considérer comme un faux positif.

    Tu peux aussi modifier ton code de manière à ne plus voir ce message. Les destructeurs des objets statiques globaux sont évalué dans l'ordre inverse de la completion des constructeurs de ces objets. Du coup, si le constructeur de A crée un objet statique quelconque, le constructeur va se terminer avant celui de A et donc le destructeur sera appelé après. Du coup :

    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
     
    class MemChecker
    {
    private:
      MemChecker() { _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); }
      ~MemChecker() { _CrtDumpMemoryLeaks(); }
    public:
      MemChecker& instance() { static MemChecker mc; return mc; }
    };
     
    class A
    {
    private:
      A() { MemChecker::instance(); } // force la création de MemChecker
      ~A() { } // ce destructeur sera évalué avant celui de MemChecker
    public:
      A& instance() { static A a; return a; }
    };
     
    int main()
    {
      A::instance();
    }
    Je ne peux pas tester le code, mais il devrait fonctionner, modulu les erreurs de compilations s'il y en a. En t'assurant que tous les constructeurs de tous les singletons que tu utilises appellent MemChecker::instance(), tu garantis que son constructeur sera appelé en dernier. C'est la norme qui le dit - tout autre comportement serait un bug du compilateur.

    Sur un autre sujet, la réponse est peut-être "est-ce que tu es vraiment sur d'avoir besoin d'un singleton ?", mais c'est une autre histoire (il me fallait quand même poser la question )
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Points : 3 156
    Points
    3 156
    Par défaut
    Sinon une bonne solution est aussi de se passer de singletons, voir ceci et ceci.
    Find me on github

  4. #4
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Salut Emmanuel,

    Merci pour votre réponse et votre exemple, j'avais eu un début de réponse sur le net mais je dois dire que tout ça restait un peu flou, c'est maintenant plus claire.

    Votre classe fonction très bien merci. Je n'ai effectivement plus de message de fuite de mémoire. Sur tout que dans mon application, mon singleton étant rattacher à un vecteur que je prenez soin de remplir, ça faisait beaucoup de "memory leak" à en perdre les cheveux

    Si non pour répondre à votre question sur l'emploie des singletons, c'est la meilleur solution que j'ai pu trouver pour répondre à mon problème malgré les inconvénients de ces derniers. Je les utilise pour un projet exploitant Opengl et un nombre conséquent de ressources. Cela me sert principalement pour des objets complexes partageant plusieurs ressources communes telles que des textures, shaders ou autres et le fait d'utiliser un singleton me simplifie grandement la tâche afin d'éviter des redondances dans le chargement en mémoire de ressources identiques.
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  5. #5
    Membre actif Avatar de Robxley
    Homme Profil pro
    Docteur ingénieur traitement d'image
    Inscrit en
    Mai 2009
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Docteur ingénieur traitement d'image

    Informations forums :
    Inscription : Mai 2009
    Messages : 158
    Points : 228
    Points
    228
    Par défaut
    Je me disais bien lors de mes recherches sur le net du singleton que j'avais déjà croisé votre nom, Emmanuel Deloget.

    http://blog.emmanueldeloget.com/inde...e-singletonite
    Rien ne sert de courir, mieux vaut partir à point. Programmer aussi d'ailleurs.
    Surtout, mais surtout pas d’astuces !
    Pas de bras, pas de chocolat. Les deux mains sur le clavier.

  6. #6
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Bonjour à tous,

    Moi ce que je ne comprend pas dans cette histoire c'est:
    Citation Envoyé par Robxley Voir le message
    J'ai repris le même code avec un simple tableau à la place d'un std::vector et je n'ai plus d'après de débugger de fuite de mémoire.
    Que l'on utilise des tableau "C style" ou des conteneur de la STL, on devrait avoir le même comportement non?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

  7. #7
    screetch
    Invité(e)
    Par défaut
    l'instance n'a pas été allouée avec new, il n'y a que le std::vector qui alloue dynamiquement.

    L'instance est effectivement leakée mais sans allocation dynamique c'est invisible

  8. #8
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Ha okay! J'ignorais de le savoir
    Merci screetch
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

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