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

MFC Discussion :

[MFC] A la chasse au memory leak


Sujet :

MFC

  1. #1
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut [MFC] A la chasse au memory leak
    Bonjour tout le monde,

    Bon j'ai un application qui commence a devenir assez grosse (~15000 lignes) en MFC sous VC++6.0. Depuis le d�but j'ai eu la gestion de la m�moire en priorit�. Et pourtant il persiste quelques memory leak dont un particuli�rement bizarre.
    En fait au lancement mon appli charge un fichier en m�moire. Pour tester j'ai fais une simple dialog box avec un bouton pour charger le fichier et un pour d�sallouer tout ce que j'alloues au chargement du fichier.
    Voil� un ptit trace de ce que me donne ctrl+alt+suppr en terme de m�moire utilis�e :
    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
     
    2144  ko (déchargé)
    21732 ko (chargé)
    2372  ko (déchargé) ML : 228 ko
    21748 ko (chargé)
    2380  ko (déchargé) ML : 8 ko
    21752 ko (chargé)
    2384  ko (déchargé) ML : 4 ko
    21752 ko (chargé)
    2384  ko (déchargé) ML : 0 ko
    21768 ko (chargé)
    2400  ko (déchargé) ML : 16 ko
    21776 ko (chargé)
    2408  ko (déchargé) ML : 8 ko
    21780 ko (chargé)
    2412  ko (déchargé) ML : 4 ko
    21780 ko (chargé)
    2412  ko (déchargé) ML : 0 ko
    Bon que ca prenne 21Mo c'est tout � fait normal et c'est pas ca le prob. Le prob c'est que je charge un fichier dans un char*, et que quand je delete[] ce char* eh ben ca r�cup�re pas toute la m�moire. Bon je peux vous montrer un peu de code mais rien d'extraordinaire :

    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
     
    void CMonApp::Load()
    {
    	ifstream f;
    	f.open(Path,ios::binary);
     
    	if(!f.is_open())
    	{
    		// gestion de l'erreur (code inutile dans le cadre de ce problème
    	}
     
    	LoadDialog *Load_dlg = new LoadDialog;
    	Load_dlg->Create(IDD_LOAD,NULL);
    	Load_dlg->ShowWindow(SW_SHOW);
    	Load_dlg->UpdateWindow();
     
    	unsigned long len = theApp.File_GetSize(f);
    	unsigned long pos = 0;
     
    	Buffer     = new char[len+1];
    	Buffer_Len = len;
    	f.read(theApp.Buffer,len);
    	f.close();
     
    	Load_dlg->DestroyWindow();
     
    	// Là j'utilise le début du Buffer et donc j'en ai plus besoin, je le désalloue partiellement via :
     
    	Reloc(seek);
    }
     
    void CMonApp::Reloc(const int seek)
    {
    	int new_size = Buffer_Len-seek;
     
    	char * Temp_Buffer = new char[new_size+1];
     
    	memcpy(Temp_Buffer,Buffer+seek,new_size);
     
    	delete[] Buffer;
     
    	Buffer = new char[new_size+1];
     
    	memcpy(Buffer,Temp_Buffer,new_size);
     
    	Buffer_Len = new_size;
     
    	delete[] Temp_Buffer;
    }
     
    // Et voilà la fonction que j'utilise pour déchargé le tout de la mémoire :
     
    void CMonApp::UnLoad()
    {
    	if(Buffer)
    	{
    		delete[] Buffer;
    	}
    }
     
    // Par rapport au new fais dans la fonction Load et pour lequel il n'y a pas de delete il se trouve dans la classe :
    void LoadDialog::OnDestroy() 
    {
    	CDialog::OnClose();
     
    	delete this;
    }
    Je code sous VC++ 6.0, d'o� peut venir le memory leak dans ce code ? (il n'y a que ce code qui est execut� quand j'appuie sur les 2 boutons). Je pr�cise que le trave est diff�rent a chaque execution mais on retrouve toujours cette sorte de "cycle" (16 - 8 - 4 - 0). Une id�e ?

  2. #2
    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 ,
    dans ton source tu as la definition suivante dans l'ent�te ?
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    en mode debug trace est ce que vc dans l'onglet debug signal du leak en sortie de prog ?


  3. #3
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Oui :
    Citation Envoy� par VC++ 6.0
    Detected memory leaks!
    Dumping objects ->
    D:\Prog\MonApp\MonApp.cpp(493) : {204} client block at 0x00303030, subtype 0, 168 bytes long.
    a CDialog object at $00303030, 168 bytes long
    Object dump complete.
    La lignes 493 c'est un new que je fais sur un bo�te de dialogue qui s'affiche juste apr�s le chargement du fichier (c'est vrai j'ai oubli� de le pr�ciser) mais il y a bien dans le code une surcharge de l'�v�nement OnClose qui demande pour sauvegarder puis delete this. Donc bizarre

  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
    re,
    une chose comme �a ,quand tu fais cette sequence :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    LoadDialog *Load_dlg = new LoadDialog;
       Load_dlg->Create(IDD_LOAD,NULL);
       Load_dlg->ShowWindow(SW_SHOW);
       Load_dlg->UpdateWindow();
    apres le UpdateWindow(); vu que c'est pas modal �a continue directement derriere ,il n'y a pas d'attente .
    donc je comprends pas trop la logique de ce qui suit sauf si tu as alleg� le code
    cette sequence me parait bizarre non?
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    void LoadDialog::OnDestroy()
    {
       CDialog::OnClose();
    appeler OnClose dans OnDestroy() c'est plutot la fonction de la classe de base OnDestroy() non ?

  5. #5
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Citation Envoy� par farscape
    re,
    une chose comme �a ,quand tu fais cette sequence :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
     
    LoadDialog *Load_dlg = new LoadDialog;
       Load_dlg->Create(IDD_LOAD,NULL);
       Load_dlg->ShowWindow(SW_SHOW);
       Load_dlg->UpdateWindow();
    apres le UpdateWindow(); vu que c'est pas modal �a continue directement derriere ,il n'y a pas d'attente .
    donc je comprends pas trop la logique de ce qui suit sauf si tu as alleg� le code
    cette sequence me parait bizarre non?
    Le fichier fais 19 Mo c'est assez long � charger en m�moire donc j'ai une simple fen�tre avec un contr�le static qui dit "merci de patienter" et qui se d�truit une fois le fichier charg� (c'est le read() qui prends entre 2 et 5 secondes).

    Citation Envoy� par farscape
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
     
    void LoadDialog::OnDestroy()
    {
       CDialog::OnClose();
    appeler OnClose dans OnDestroy() c'est plutot la fonction de la classe de base OnDestroy() non ?
    C'est Visual qui m'a pondu ce code c'est pas moi. J'ai juste mit le delete moi

  6. #6
    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
    a mon avis tu as du chang� en cours de route ,c'est CDialog::OnDestroy();
    qui est g�n�r� par defaut.

  7. #7
    Membre Expert
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Par d�faut
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    LoadDialog *Load_dlg = new LoadDialog;


    Load_dlg est d�truit quand ?

  8. #8
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Citation Envoy� par la drogue c'est mal
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
     
    LoadDialog *Load_dlg = new LoadDialog;


    Load_dlg est d�truit quand ?
    Lors de l'appel Load_dlg->DestroyWindow() il y a un delete :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    void LoadDialog::OnDestroy()
    {
       CDialog::OnClose();
     
       delete this;
    }

    Citation Envoy� par farscape
    a mon avis tu as du chang� en cours de route ,c'est CDialog::OnDestroy();
    qui est g�n�r� par defaut.
    Very Happy
    Ca m'�tonne vraiment beaucoup c'est le genre de truc auquel je touche pas mais bon je vais voir d�s que je peux (je ne suis plus sous win l� ).

  9. #9
    R�dacteur
    Avatar de abelman
    Inscrit en
    F�vrier 2003
    Messages
    1 106
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2003
    Messages : 1 106
    Par d�faut
    Pour la fermeture du dialogue intercepte plutot WM_CLOSE au lieu de WM_DESTROY . Supprime la fonction OnDestroy et fais
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
     
    void LoadDialog::OnClose()
    {
       DestroyWindow();
       delete this;
    }

  10. #10
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Tiens j'ai fais :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    void CWDA_LoadDialog::OnClose() 
    {
    	CDialog::OnClose();
     
    	delete this;
    }
    Au lieu de OnDestroy() et j'ai modifie le LoadDlg->DestroyWindow() en LoadDlg->SendMessage(WM_CLOSE); et a plus de memory leak

  11. #11
    R�dacteur
    Avatar de abelman
    Inscrit en
    F�vrier 2003
    Messages
    1 106
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2003
    Messages : 1 106
    Par d�faut
    oui car CDailog::OnClose par d�faut appelle DestroyWindow()

  12. #12
    Membre Expert
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Par d�faut
    mon dieux j'avais pas vu .... c'est � l'epita qu'on t'as appris � faire ca ??


    parce que limite tout pourri ca

  13. #13
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Citation Envoy� par la drogue c'est mal
    mon dieux j'avais pas vu .... c'est � l'epita qu'on t'as appris � faire ca ??


    parce que limite tout pourri ca
    Etant donn� que j'y suis pas encore (seulement a cette rentr�e) non ca n'est pas l� qu'on me l'a appris. Limite tout pourri ? Sachant que je ne peux pas delete directement l'objet depuis le code je n'ai pas le choix. Si tu as mieux n'h�site pas ...

  14. #14
    Membre Expert
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Par d�faut
    Sachant que je ne peux pas delete directement l'objet depuis le code
    et pourquoi ?

  15. #15
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Ben avec une fen�tre non-modale ton code continue et tu ne sais jamais quand il ne faudra plus utiliser l'objet sauf si tu surveille l'event OnClose() o� tu sais que tu peux delete sans probl�me ton objet ...

  16. #16
    Membre Expert
    Avatar de la drogue c'est mal
    Profil pro
    Inscrit en
    Novembre 2002
    Messages
    2 253
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 2 253
    Par d�faut
    si tu veux faire ca, fais le dans le bon message. Surcharge la methode virtuel PostNcDestroy() ( de la classe CWnd ). Comme c'est ecrit dans le msdn, c'est fait pour ca :

    Derived classes can use this function for custom cleanup such as the deletion of the this pointer.
    PostNcDestroy est fait expres pour impl�menter les delete this.

  17. #17
    R�dacteur
    Avatar de abelman
    Inscrit en
    F�vrier 2003
    Messages
    1 106
    D�tails du profil
    Informations forums :
    Inscription : F�vrier 2003
    Messages : 1 106
    Par d�faut
    Tu peux bien sur faire un delete sur l'objet dialog, si tu en fais un membre de ta classe (delete dans le destructeur) et non une variable locale � une fonction

  18. #18
    Membre tr�s actif
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    258
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 258
    Par d�faut
    Citation Envoy� par abelman
    Tu peux bien sur faire un delete sur l'objet dialog, si tu en fais un membre de ta classe (delete dans le destructeur) et non une variable locale � une fonction
    Certes mais ca veut dire attendre la fin du programme (puisque c'est la classe de l'objet theApp) avant de lib�rer la m�moire.

    Citation Envoy� par la drogue c'est mal
    si tu veux faire ca, fais le dans le bon message. Surcharge la methode virtuel PostNcDestroy() ( de la classe CWnd ). Comme c'est ecrit dans le msdn, c'est fait pour ca :

    Derived classes can use this function for custom cleanup such as the deletion of the this pointer.
    PostNcDestroy est fait expres pour impl�menter les delete this.
    Merci je ne connaissais pas cette fonction Apr�s tout on est tous l� pour apprendre non ?

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. R�ponses: 8
    Dernier message: 28/10/2010, 20h08
  2. Compilation TAO / Mfc : Memory Leaks
    Par Rolsct dans le forum CORBA
    R�ponses: 4
    Dernier message: 17/04/2005, 19h13
  3. [MFC] Thread & memory leaks
    Par Racailloux dans le forum MFC
    R�ponses: 7
    Dernier message: 15/03/2005, 12h44
  4. Memory leak en C/C++
    Par Roswell dans le forum Autres �diteurs
    R�ponses: 6
    Dernier message: 07/07/2004, 19h41
  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