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

Visual C++ Discussion :

Risque de memory leak selon un analyseur


Sujet :

Visual C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut Risque de memory leak selon un analyseur
    Bonjour!

    Klocwork l'analyseur de code statique dit que: Possible memory leak. Dynamic memory stored in 'pSETEndFittingProductFamilies' allocated through function 'new' dans ma partie de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	else
    	{
          m_pSubEntityTypesToLoad = new CSubEntityTypesToLoad();
          CSubEntityTypeToLoad* pSETConnectedSemiEquipments = new CSubEntityTypeToLoad(enEProcessSETConnectedSemiEquipments, NULL);
          CSubEntityTypeToLoad* pSETEquProductFamilies = new CSubEntityTypeToLoad(enEProcessSETEquProductFamilies, NULL);
     
          if (m_pSubEntityTypesToLoad && pSETConnectedSemiEquipments/* && pSETEquProductFamilies*/)
          {
             m_pSubEntityTypesToLoad->push_back(pSETConnectedSemiEquipments);
             m_pSubEntityTypesToLoad->push_back(pSETEquProductFamilies);
          }		
    	}
    alors qu'il semble, j'en suis sur qu'il n'y en a pas
    Il s'agit en fait d'une classe héritant un std::vector<>

    Il y a bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void CVectorSubEntityTypesToLoad::Clear()
    {
    	for(long i = 0; i < (long)size(); i++)
    		delete at(i);
     
    	clear();
    }
    Pensez vous que le leak est possible?

    Source:
    TestMemoryLeakVector.zip
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Eh bien, pour commencer, ce code n'est pas exception-safe, donc si l'un des trois new lance une exception std::bad_alloc parce qu'il n'y a plus de mémoire (ou si l'un des constructeurs lance une exception), il y aura fuite...

    Et plus simplement, si le test est faux, tes deux pointeurs locaux seront leakés...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Eh bien, pour commencer, ce code n'est pas exception-safe, donc si l'un des trois new lance une exception std::bad_alloc parce qu'il n'y a plus de mémoire (ou si l'un des constructeurs lance une exception), il y aura fuite...

    Et plus simplement, si le test est faux, tes deux pointeurs locaux seront leakés...
    Ah bon ! Il y a donc allocation puis s'il y aerreur et l'espace allouée ne sera jamais désallouée?

    Mais si aucune exception, il n'est pas POSSIBLE une memory leak?

    Pourquoi l'analyseur précise ces 2 lignes seulement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          CSubEntityTypeToLoad* pSETConnectedSemiEquipments = new CSubEntityTypeToLoad(enEProcessSETConnectedSemiEquipments, NULL);
          CSubEntityTypeToLoad* pSETEquProductFamilies = new CSubEntityTypeToLoad(enEProcessSETEquProductFamilies, NULL);
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  4. #4
    Rédacteur
    Avatar de farscape
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    9 055
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2003
    Messages : 9 055
    Par défaut
    salut,
    peut être parce qu'il ne voit pas de libération explicite de ces deux pointeurs.
    et que le stockage de leur valeur est conditionnel donc risque de fuite.

  5. #5
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut
    peut être parce qu'il ne voit pas de libération explicite de ces deux pointeurs.
    Si vous parlez de Klocwork: si! Il voit les delete par boucle des objets pointés par des vector<>, list<>, etc.
    Mais le dire de Médinoc m'intrigue un peu:
    si l'un des trois new lance une exception std::bad_alloc parce qu'il n'y a plus de mémoire (ou si l'un des constructeurs lance une exception), il y aura fuite
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Citation Envoyé par randriano Voir le message
    Si vous parlez de Klocwork: si! Il voit les delete par boucle des objets pointés par des vector<>, list<>, etc.
    Sauf que si ton if (m_pSubEntityTypesToLoad && pSETConnectedSemiEquipments) n'est pas satisfait, tes pointeurs ne seront jamais ajouté au vecteur et seront leakés...
    Mais le dire de Médinoc m'intrigue un peu:
    C'est pourtant simple:
    • Tu alloues le premier objet CSE, ça marche, le seul pointeur vers cet objet est un pointeur bète dans une variable locale.
    • Tu tentes d'allouer le second objet EPF, mais il n'y a plus de mémoire: Une exception bad_alloc est lancée.
    • Le seul pointeur vers l'objet CSE est détruit et il n'y a rien pour faire un delete dessus: L'objet CSE est leaké.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut
    Sauf que si ton if (m_pSubEntityTypesToLoad && pSETConnectedSemiEquipments) n'est pas satisfait, tes pointeurs ne seront jamais ajouté au vecteur et seront leakés...
    D'accord je comprend maintenant ce cas , il faut ajouter un traitement du genre ??
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       else
          if (!m_pSubEntityTypesToLoad)
          {
             if (pSETEndFittingProductFamilies)
                delete pSETEndFittingProductFamilies;
             if (pSETEquProductFamilies)
                delete pSETEquProductFamilies;
          }
    Pour le fait que quelque chose m'intrigue,
    Tu tentes d'allouer le second objet EPF, mais il n'y a plus de mémoire: Une exception bad_alloc est lancée
    Comment le gérer alors? try catch()?
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Juste un else devrait suffire, pas besoin d'y mettre un second if en plus.
    De plus, inutile de tester tes pointeurs avant le delete:
    • Tes pointeurs ne seront jamais nuls car sur tout compilo conforme, new lance une exception en cas d'échec
    • Même s'ils sont nuls, delete l'accepte.


    Pour le problème, il faut ne pas gérer "manuellement" plus d'une ressource à la fois. Je recommande d'utiliser une classe de pointeur intelligent (ici, même std::auto_ptr<> devrait marcher), sans oublier de "détacher" le pointeur quand tu ajoutes l'objet au vecteur (std::auto_ptr<>::release()).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Pour le problème, il faut ne pas gérer "manuellement" plus d'une ressource à la fois. Je recommande d'utiliser une classe de pointeur intelligent (ici, même std::auto_ptr<> devrait marcher), sans oublier de "détacher" le pointeur quand tu ajoutes l'objet au vecteur (std::auto_ptr<>::release()).
    Plein de truc la STL!!

    Mais concernant la possible fuite à cause de std::bad_alloc, ça arrive souvent???
    J'hésite un peu à la gérer car je ne pense pas que c'est ça que Klocwork soupçonnait non?
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Ce n'est clairement pas ça qu'il soupçonnait, et typiquement, quand une exception bad_alloc est lancée, tu as d'autres soucis.
    Par contre, si un des constructeurs est susceptible de lancer une autre exception, ben...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Membre extrêmement actif
    Avatar de randriano
    Homme Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 221
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 221
    Par défaut
    Et ben C++ et ses soucis, ça n'en finit jamais
    Sincèrement, les fuites et autres erreurs qui peuvent être causées par un NEW, je n'y ai jamais pensé jusqu'à maintenant
    Peux-tu me donner un exemple de gestion de cela?
    randriano.dvp.com
    Développeur. Product Owner [Agile]. Sites web, mobile apps, système d'information (SI).

Discussions similaires

  1. Compilation TAO / Mfc : Memory Leaks
    Par Rolsct dans le forum CORBA
    Réponses: 4
    Dernier message: 17/04/2005, 19h13
  2. [MFC] Thread & memory leaks
    Par Racailloux dans le forum MFC
    Réponses: 7
    Dernier message: 15/03/2005, 12h44
  3. Memory leak en C/C++
    Par Roswell dans le forum Autres éditeurs
    Réponses: 6
    Dernier message: 07/07/2004, 19h41
  4. [MFC] A la chasse au memory leak
    Par Yabo dans le forum MFC
    Réponses: 17
    Dernier message: 27/06/2004, 17h35
  5. Réponses: 7
    Dernier message: 26/02/2004, 09h32

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