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 :

fuite de mémoire Gdiplus


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut fuite de mémoire Gdiplus
    Bonjour, j'ai fait un classe Screen qui charge un bitmap de l'image à l'écran, mais lorsque je fait une boucle contenant le constructeur et destructeur de cette classe, j'ai la ram qui se remplie. J'ai essayé de delete(scnBmpData) et delete(scnOct) mais ça fait cracher mon programme. Je suis débutant en programmation et ça fait 1 semaine que mon programme est bloqué à cause de ça. Si quelqu'un pouvait m'aider j'en serais reconaissant. Merci d'avance.

    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
    screen::screen()
    {  
      // Donne les dimensions de l'écran
      int x1, y1, x2, y2;
      x1  = GetSystemMetrics(SM_XVIRTUALSCREEN);
      y1  = GetSystemMetrics(SM_YVIRTUALSCREEN);
      x2  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
      y2  = GetSystemMetrics(SM_CYVIRTUALSCREEN);
      this->w   = x2 - x1;
      this->h   = y2 - y1;
     
      // copie l'écran dans le bitmap
      this->hScreen = GetDC(NULL);
      this->hDC     = CreateCompatibleDC(hScreen);
      this->hBitmap = CreateCompatibleBitmap(hScreen, w, h);
      HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
      BOOL    bRet    = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
     
      //Charge le bitmap dans le buffer
      this->scnBmp = new Gdiplus::Bitmap(hBitmap,NULL);
      Gdiplus::Rect rectScnBmp(0,0, w, h);
      this->scnBmpData = new Gdiplus::BitmapData;
      scnBmp->LockBits(&rectScnBmp, Gdiplus::ImageLockModeRead,
    		   PixelFormat32bppARGB, scnBmpData);
      this ->scnOct = (byte*)(void*)scnBmpData->Scan0;
    }
    screen::~screen()
    {
      scnBmp->UnlockBits(scnBmpData);
      DeleteDC(hDC);
      ReleaseDC(NULL, hScreen);
      DeleteObject(hBitmap);
      delete(scnBmpData);
    }
    //ma boucle qui fait monter la ram, mais qui marche quand même.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     while(!pos.x && !pos.y)
      {
        screen monEcran;
        //pos = monEcran.findBmp(monbmp);
        monEcran.~screen();
        //if(pos.x && pos.y)
        //  cout << "trouvé en: (" << pos.x << ","<< pos.y << ")"<< endl;
      }
    edit: j'ai trouvé (en fait non)

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Je vois au moins un new sans delete, sur scnBmp
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    j'ai déplacé la partie buffer dans une autre partie du programme et j'ai delete le plus possible de choses mais ça n'a pas l'air de marcher, en fait dès que je lance le programme le programme atteint les 3go de ram très vite et il y reste. Et même avec un sleep(1000) il finit par les atteindre.

    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
    screen::screen()
    {  
      // get screen dimensions
      int x1, y1, x2, y2;
      x1  = GetSystemMetrics(SM_XVIRTUALSCREEN);
      y1  = GetSystemMetrics(SM_YVIRTUALSCREEN);
      x2  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
      y2  = GetSystemMetrics(SM_CYVIRTUALSCREEN);
      this->w   = x2 - x1;
      this->h   = y2 - y1;
     
      // copy screen to bitmap
      this->hScreen = GetDC(NULL);
      this->hDC     = CreateCompatibleDC(hScreen);
      this->hBitmap = CreateCompatibleBitmap(hScreen, w, h);
      HGDIOBJ old_obj = SelectObject(hDC, hBitmap);
      BOOL    bRet    = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
      this->scnBmp = new Gdiplus::Bitmap(hBitmap,NULL);
     
      DeleteObject(old_obj);
     }
    screen::~screen()
    {
      DeleteDC(hDC);
      ReleaseDC(NULL, hScreen);
      DeleteObject(hScreen);
      DeleteObject(hBitmap);  
      DeleteObject(scnBmp);
    }

  4. #4
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Pour quelle raison fais-tu un appel explicite au destructeur ?

    L'objet est détruit et le destructeur appeler tout seul à la fin de sa vie/portée.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    je savais pas ça merci, mais le problème vient pas de là.

    edit: c'est à partir du bitblt que ça merde

  6. #6
    Membre expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2011
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 739
    Points : 3 627
    Points
    3 627
    Par défaut
    Il manque le delete sur scnBmp, comme l'a indiqué Bousk.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    j'ai déjà essayé ça fait cracher le programme, je pense le bitmap n'est pas libéré correctement car ça fuit de 9mo par passage dans la boucle.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Pas sûr à 100% mais je pense que c'est la variable old_obj qui n'est pas libérée.

    Dans les codes Internet, cette variable est sauvegardée et après l'opération, elle est "remise en place" SelectObject(XXXDC, old_obj); afin d'avoir "le même état" avant et après.

    Dans ton cas, il faut peut être juste faire un DeleteObject(old_obj);.


    Édit: dans ta deuxième version tu le fais déjà

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    Oui je viens de voir ça, par contre ça change rien. La seule chose efficace pour le moment c'est de commenter l'initialisation du bitmap.
    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
    screen::screen()
    {  
      // get screen dimensions
      int x1, y1, x2, y2;
      x1  = GetSystemMetrics(SM_XVIRTUALSCREEN);
      y1  = GetSystemMetrics(SM_YVIRTUALSCREEN);
      x2  = GetSystemMetrics(SM_CXVIRTUALSCREEN);
      y2  = GetSystemMetrics(SM_CYVIRTUALSCREEN);
      this->w   = x2 - x1;
      this->h   = y2 - y1;
     
      // copy screen to bitmap
      this->hScreen = GetDC(NULL);
      this->hDC     = CreateCompatibleDC(hScreen);
      this->hBitmap = CreateCompatibleBitmap(hScreen, w, h);
      this->old_obj = SelectObject(hDC, hBitmap);
      BOOL    bRet    = BitBlt(hDC, 0, 0, w, h, hScreen, x1, y1, SRCCOPY);
      this->scnBmp = new Gdiplus::Bitmap(hBitmap,NULL); // si je commente= => plus de fuite
     }
    screen::~screen()
    {
      ReleaseDC(NULL, hScreen);
      DeleteDC(hScreen);
      SelectObject(hDC, old_obj);
      DeleteObject(hBitmap);
      DeleteObject(scnBmp);
      DeleteObject(old_obj);
      DeleteDC(hDC);
    }
    edit: le Bitmap se libère en faisant un delete apparemment, donc je comprends pas pourquoi ça crache, peut être qu'il se libère à la fin du constructeur mais je ne vois pas pourquoi

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Février 2012
    Messages
    83
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2012
    Messages : 83
    Points : 56
    Points
    56
    Par défaut
    J'ai trouvé vos réponses font sens maintenant
    En fait il fallait juste faire un delete scnBmp et supprimer l'appel du destructeur.
    Merci bien !

    Mon programme consomme do,c que 9mb et 1% cpu pour trouver un bmp à l'écran en temps réel, le lockbits est définivement meilleur que getpixel

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

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

Discussions similaires

  1. fuite de mémoire ?
    Par salseropom dans le forum C
    Réponses: 2
    Dernier message: 12/01/2006, 16h19
  2. Réponses: 1
    Dernier message: 02/12/2005, 14h18
  3. fuite de mémoire
    Par mamag dans le forum MFC
    Réponses: 17
    Dernier message: 19/08/2005, 10h42
  4. Fuite de mémoire en utilisant le template list
    Par schtroumpf_farceur dans le forum Langage
    Réponses: 9
    Dernier message: 18/07/2005, 20h44
  5. Réponses: 8
    Dernier message: 17/10/2002, 12h52

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