Что нового

Про утечку памяти

asdf8

Скриптер
Сообщения
564
Репутация
152
Задался вопросом - какие-же ресурсы нужно обязательно освобождать во время работы и перед окончанием работы скрипта?
На мысль натолкнула эта тема.
В данном случае речь идет об удалении битмапа, который устанавливается функцией _SendMessage в контрол GUICtrlCreatePic.
С одной стороны msdn говорит, что пользователь сам должен освобождать ресурсы, с другой стороны нижеприведенный код показывает, что эти ресурсы освобождаются автоматически и нет никакой утечки памяти.
Код:
#Include <GDIPlus.au3>

If Not FileExists(@ScriptDir & '\test.jpg') Then
	ConsoleWrite('! Не найден файл :' & @CRLF & @ScriptDir & '\test.jpg' & @CRLF)
	Exit
EndIf

_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & '\test.jpg')
$hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

GUICreate("Test")
GUISetState(@SW_SHOW)

While 1
	If GUIGetMsg() = -3 Then Exit
	$Pic = GUICtrlCreatePic("", 0, 0)
	_SendMessage(GUICtrlGetHandle($Pic), 0x0172, 0, $hBitmap)
	ConsoleWrite('- Inp Bitmap >' & $hBitmap & '  Out Bitmap >0x' & Hex(_SendMessage(GUICtrlGetHandle($Pic), 0x0173), 8) & @CRLF)
	Sleep(100)
	GUICtrlDelete($Pic)
WEnd
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
При удалении Pic ресурсы освобождать не нужно, это будет сделано автоматически. А вот при вставке в Pic нужно действовать следующим образом:

  • Windows XP.
    Если изображение имеет альфа-канал (прозрачность), то HBITMAP будет скопирован, и исходное изображение необходимо удалить во избежании утечки памяти (если оно больше не нужно). Если изображение не содержит прозрачность, то оно же и будет использовано для отображения. В этом случае его удалять, естественно, нельзя.

  • Windows Vista+.
    Исходное изображение всегда копируется, следовательно всегда необходимо его удалять.

Чтобы не заморачиваться с версией Windows и определением наличия прозрачности, я делаю так:

Код:
$hPrev = _SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hBitmap)
If $hPrev Then
	_WinAPI_DeleteObject($hPrev)
EndIf
$hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
If $hPrev <> $hBitmap Then
	_WinAPI_DeleteObject($hBitmap)
EndIf
 
Верх