[Résolu] Fuite mémoire, que libérer ?

Fuite mémoire, que libérer ? [Résolu] - API Win32 - Programmation

Marsh Posté le 02-09-2009 à 14:41:50    

Bonjour,
 
Je dois avoir du mal pour libérer mes structs, pointeurs et autre parce que mon programme a de grosse fuite mémoire (quelques giga en quelques secondes). Je crois avoir isoler le probleme dans ces deux fonctions, pouvez vous m'aider a me montrer ce que j'ai oublié de libérer et comment les libérer.
 

Code :
  1. BITMAP take_screenshot()
  2. {
  3. HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
  4. HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC,
  5.       nScreenWidth, nScreenHeight);
  6. SelectObject(hCaptureDC,hCaptureBitmap);
  7. BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
  8.     hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
  9.   //Get Cursor Pos
  10.   POINT xPoint;
  11.   GetCursorPos( &xPoint );
  12.   //Draw the Cursor
  13.   bool g_recordcursor = 1;
  14.   if (g_recordcursor == 1) {
  15.     BOOL ret;
  16.     CURSORINFO cinfo;
  17. cinfo.cbSize = sizeof(CURSORINFO);
  18. ret = GetCursorInfo(&cinfo);
  19. DrawIcon( hCaptureDC,  cinfo.ptScreenPos.x,  cinfo.ptScreenPos.y, cinfo.hCursor);
  20.   }
  21. HBITMAP hNewBitmap = (HBITMAP)SelectObject(hCaptureDC, hCaptureBitmap);
  22. BITMAP bm;
  23. ZeroMemory(&bm,sizeof(BITMAP));
  24. GetObject(hNewBitmap, sizeof(bm), &bm);
  25. int bm_size = bm.bmWidthBytes * bm.bmHeight;
  26. bm.bmBits = new char[bm_size];
  27. long nfetched = GetBitmapBits(hCaptureBitmap, bm_size, bm.bmBits);
  28. DeleteDC(hCaptureDC);
  29. DeleteObject(hCaptureBitmap);
  30. DeleteObject(hNewBitmap);
  31. return bm;
  32. }
  33. static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
  34. {
  35. BITMAP bm = take_screenshot();
  36. SwsContext *fooContext = sws_getContext(nScreenWidth,nScreenHeight,PIX_FMT_RGB32,
  37.           width,height,STREAM_PIX_FMT,
  38.           sws_flags,NULL,NULL,NULL);
  39. uint8_t *movie_dib_bits = reinterpret_cast<uint8_t *>(bm.bmBits);
  40. int dibrowbytes = bm.bmWidthBytes;
  41. uint8_t* data_out[4];
  42. int stride_out[4];
  43. data_out[0] = movie_dib_bits;
  44. stride_out[0] = dibrowbytes;
  45. sws_scale(fooContext,data_out,stride_out,0,nScreenHeight,pict->data,pict->linesize);
  46. // A partir d'ici j'ai besoin de plus rien sauf pict
  47. free(movie_dib_bits);
  48. DeleteObject(&bm);
  49. }


 
Merci !


Message édité par kyom le 02-09-2009 à 16:51:53
Reply

Marsh Posté le 02-09-2009 à 14:41:50   

Reply

Marsh Posté le 02-09-2009 à 15:54:25    

Peut-être que ce serait dû à l'ordre des libérations des ressources. Essayer de les faire dans l'ordre inverse de leur création, en remplaçant les lignes 37 à 39 par :

DeleteObject(hNewBitmap);
DeleteObject(hCaptureBitmap);
DeleteDC(hCaptureDC);


Reply

Marsh Posté le 02-09-2009 à 15:57:08    

Aucun changement...

Reply

Marsh Posté le 02-09-2009 à 16:16:33    

Autre chose.

BITMAP take_screenshot()
{
...
BITMAP bm;
...
return bm;
}
 
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
{
BITMAP bm = take_screenshot();
...


La ligne BITMAP bm;réserve de l'espace sur la pile pour la structure bm, par exemple à l'adresse 1234.
La ligne return bm renvoie 1234, mais ne renvoie pas le contenu de la structure.
La ligne BITMAP bm = take_screenshot();associe 1234 au nouveau bm
Ensuite la pile est altérée par la suite du programme, ce qui est normale, et donc les octect à l'adresse 1234 ne veulent plus rien dire.
 
Pour le passage de paramètres, il faut procéder autrement. Il faut les mettre dans les paramètres de la fonction, et non pas dans le pointeur de retour d'une fonction, et il ne faut pas les allouer à l'intérieur d'une sous fonction, mais les allouer à l'extérieur, et donc écrire :

int take_screenshot(... BITMAP bm ...)
{
...
...bm...
...
return 0;
}
 
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height)
{
int code_retour;
BITMAP bm;
code_retour = take_screenshot(...bm...);
...


Message édité par olivthill le 02-09-2009 à 16:18:15
Reply

Marsh Posté le 02-09-2009 à 16:18:09    

Hmm, il y a un truc qui me parait être la cause, c'est ton premier appel à SelectObject, ça devrait plutôt être :

Code :
  1. HBITMAP old = SelectObject(hCaptureDC,hCaptureBitmap);


 
Et avant de libérer ton DC, il faut toujours remettre les valeurs d'origine avec GDI :

Code :
  1. SelectObject(hCaptureDC, old);
  2. DeleteDC(hCaptureDC);


 
Et ton hNewBitmap ne sert à rien, ton second appel à SelectObject va te renvoyer un pointeur sur hCaptureBitmap.
 
Edit: oh purée, je n'avais pas vu ton "DeleteObject(&bm);" à la fin. Incroyable que ça ne fasse pas planter ton programme. &bm n'est pas du tout un handle de bitmap, fait simplement un "delete[] bm.bmBits".
 
Edit2: [:prozac] purée et tu fais un reinterpret_cast sur bm.bmBits dans un uint8_t *, que tu passes à la fonction free(), apràs l'avoir alloué avec new char[x].


Message édité par tpierron le 02-09-2009 à 16:29:23
Reply

Marsh Posté le 02-09-2009 à 16:50:45    

Merci bien, avec toute ces modifs ça fonctionne bien mieux.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed