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 :

Fuite mémoire et désapointement


Sujet :

Visual C++

  1. #1
    Membre émérite
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Par défaut Fuite mémoire et désapointement
    Bonjour.

    J'ai un problème de fuite mémoire dans un code sous VC++6.
    J'utilise un controle CWebBrowser, et a chaque fois que la fenetre est rafraichie (apres le rafraichissement pour etre precis) :

    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
     
     
                 lpDispatch = m_browser.GetDocument(); // m_browser est mon CWebBrowser2
    	IHTMLDocument2 *doc2 = NULL;
    	lpDispatch->QueryInterface(IID_IHTMLDocument2,(void**)&doc2);
    	if ( doc2 == 0 )
    		return;
    	IHTMLElement *lpBodyElement; 
    	IHTMLBodyElement *lpBody; 
    	IHTMLTxtRange *lpText; 		
    	doc2->get_body(&lpBodyElement); 
    	if ( lpBodyElement )
    	{
    		lpBodyElement->QueryInterface(IID_IHTMLBodyElement,(void**)&lpBody); 
    		if ( lpBody )
    		{
    			lpBody->createTextRange(&lpText); 
    			BSTR bstrText; 
    			lpText->get_htmlText(&bstrText); 
     
                                          // mon traitement
    Et je fini mon traitement avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
     
    			lpBody->Release();			
    			//delete(lpBody); 	
    		}
    		//delete(lpBodyElement);
    		lpBodyElement->Release();
    	}
    	doc2->Release();
    Ce qui devrait désaloué tout ce petit monde.
    Pourtant, a chaque refresh de ma page web dans mon CWebBrowser, mon processus se prend entre 300 et 500k dans la figure... au bout de quelque heures d'utiilisation, mon processus pèse près de 70Mo alors qu'il en pesait 16 au lancement.
    Compte tenu de la taille qu'il prend a chaque refresh, je suis persuadé que c'est le contenu HTML de la page web qui est chargée en mémoire qui n'est pas désaloué.

    J'ai donc essayé des free() et des delete(), mais le résultat reste le même.
    Etant expert en PHP, mais pas du tout en C, j'aurais vraiment besoin qu'on m'explique ce qui ne vas pas...


    J'ai également essayé de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     // CString i2a(int); // converti un int en Cstring
    	MessageBox(i2a((int)doc2));
    	doc2->Release();
    	free(doc2);
    	MessageBox(i2a((int)doc2));
    Pourtant, les 2 MessageBox m'affichent le même résultat... docs ne devrait-il pas etre égale à NULL apres le free ? même chose avec delete :/

    Quelqu'un comprend t-il pourquoi ça fait ça.

    Merci d'avance.

    edit : il n'y a bien entendu pas de return dans le code

    edit2 : j'ai coupé mon code trop tot pour voir le delete sur lpText, mais je l'avais testé aussi

  2. #2
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Bonjour,

    pourquoi n'utilises-tu pas les delete (pourquoi les as-tu mis en commentaire)? Je ne trouve pas de doc sur cette méthode Release

  3. #3
    Membre émérite
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Par défaut
    A vrai dire, j'ai pompé cette partie du code sur la msdn et des forums.
    Pour le delete, je les ai mis en commantaire car c'est moi qui les avait ajouté, et que cela ne changeait strictement rien.

    Ce sont des delete, mais j'ai egalement essayé de mettre des free() sans plus de résultat...

    La combinaison Release + delete ne donne rien non plus...

    Cependant, je me pose toujours la question de savoir si c'est normal que mon pointeur indique toujours la meme adresse apres un delete. Il ne devrait pas passer a NULL ?

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gloubi
    A vrai dire, j'ai pompé cette partie du code sur la msdn et des forums.
    Pour le delete, je les ai mis en commantaire car c'est moi qui les avait ajouté, et que cela ne changeait strictement rien.

    Ce sont des delete, mais j'ai egalement essayé de mettre des free() sans plus de résultat...

    La combinaison Release + delete ne donne rien non plus...

    Cependant, je me pose toujours la question de savoir si c'est normal que mon pointeur indique toujours la meme adresse apres un delete. Il ne devrait pas passer a NULL ?
    Non.
    Losque tu fais un delete (ou un Release, puisqu'apparemment c'est la même chose) le système désalloue la mémoire mais il ne réinitialise pas le pointeur. Si tu tiens absolument à le passer à NULL (ce qui peut servir pour des tests ultérieurs par exemple) il faut le faire "à la main":

  5. #5
    Membre émérite
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Par défaut
    Et est-ce que le delete est supposé libérer de façon récursive tous les pointeurs contenus dans la class/structure passée en paramètre ?

    Cela est-il prévu dans le destroy des class que j'utilise ?

    J'ai vraiment l'impression d'être devant un problème insoluble... j'ai beau mettre des delete partout, mon prog continu a gonfler quand je le fait pas planter...

    J'ai tester en dehors de ce module, je ne fait aucun new() ni malloc() (a part une fonction de file, qui elle se désaloue bien)...

    des idées ?

  6. #6
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 288
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par gloubi
    Et est-ce que le delete est supposé libérer de façon récursive tous les pointeurs contenus dans la class/structure passée en paramètre ?
    Si la classe concernée est bien programmée, oui. Si c'est une classe que tu implémentes toi-même, c'est à toi de gérer la libération de mémoire des objets qu'elle contient.

    Citation Envoyé par gloubi
    Cela est-il prévu dans le destroy des class que j'utilise ?
    C'est une classe de la MFC, donc sans hésitation: oui.

    Citation Envoyé par gloubi
    J'ai vraiment l'impression d'être devant un problème insoluble... j'ai beau mettre des delete partout, mon prog continu a gonfler quand je le fait pas planter...

    J'ai tester en dehors de ce module, je ne fait aucun new() ni malloc() (a part une fonction de file, qui elle se désaloue bien)...

    des idées ?
    Comme ça, c'est difficile. Les fuites mémoires sont souvent difficiles à localiser. Beaucoup de sujets en parlent sur le site, avec une petite recherche, tu devrais trouver beaucoup d'indications. Par exemple: http://www.developpez.net/forums/sho...uite+m%E9moire

  7. #7
    Membre émérite
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Par défaut
    Merci pour la piste, je vais potasser ça et je vous tien au courrant

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 394
    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 394
    Par défaut
    Attention, pour une interface COM/OLE, il ne faut faire ni delete ni free().
    Juste l'appel à Release(), puis on met le pointeur à NULL.

    Normalement, il faut à un Release "par interface".
    C'est-à-dire que chaque appel à CoCreateInstance(), QueryInterface() ou AddRef() doit avoir un Release() qui lui correspond (et à mon avis, le GetDocument() contient un AddRef(), donc il faudra faire Release() à la fin).

    Note: Évitez de tester les pointeurs en retour de QueryInterface() : C'est la valeur de retour qu'il faut tester, avec la macro SUCCEEDED() ou FAILED().
    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 éprouvé
    Inscrit en
    Avril 2004
    Messages
    122
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 122
    Par défaut
    Salut,
    Effectivement, apparemment il manque un release sur lpDispatch et j'ajouterai aussi que les BSTR doivent être désaloués une fois que l'on ne les utilise plus ou avant de les réutiliser avec un jolie SysfreeString sinon grosses pertes de blocs !

  10. #10
    Membre émérite
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Par défaut
    meric beaucoup ^^
    je vais jetter un oeil a tout ça :p

Discussions similaires

  1. [tomcat][memoire] java.net.URL et fuite mémoire
    Par Seiya dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 09/03/2009, 10h41
  2. [Fuites mémoire] Je cherche un utilitaire
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 8
    Dernier message: 10/02/2005, 10h03
  3. Outil de recherche de fuite mémoire
    Par eag35 dans le forum MFC
    Réponses: 4
    Dernier message: 02/02/2005, 12h46
  4. [SWT]SWT et fuite mémoire(ou pas)
    Par menuge dans le forum SWT/JFace
    Réponses: 2
    Dernier message: 22/06/2004, 21h40
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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