最近給程序加了一個動畫功能后,發現程序會引起及其嚴重的內存泄露,找了半天發現是調用STM_SETIMAGE
引起的。素以在此將使用STM_SETIMAGE
遇到的問題記錄一下。 我的程序將動畫的所有幀提前加載后用定時器循環用STM_SETIMAGE
把位圖句柄發送到窗口顯示,發現沒顯示一次就泄露好幾M內存,而且動畫切換的速度是很快的,所以不一會就開始bad_alloc
了。 為什么每發送一次STM_SETIMAGE
就泄露呢?查看msdn
關于STM_SETIMAGE
的說明,最后有一段描述,原文不貼了,翻譯過來大概就是這樣: 在xp下(xp以上應該也是),如果顯示的位圖有非零的透明通道的像素(我自己翻譯的),控件就會復制一份位圖,這個復制的位圖的句柄將在下次調用STM_SETIMAGE
時作為返回值返回,調用者有責任釋放這個位圖,不然就會內存泄露。 解決方法: 我不知道微軟內部用了怎樣的實現才會導致有這樣奇葩的使用方式,而且目前我也不知道怎樣判斷什么叫做“有非零的透明通道的像素”,所以只能通過判斷返回的句柄,如果創建static
控件后第一次使用STM_SETIMAGE
,會返回NULL,如果內部沒有復制位圖,那么下次調用STM_SETIMAGE
的返回值就是上次傳入的位圖句柄,如果內部有復制位圖,那么下次調用STM_SETIMAGE
的返回值就是static
控件內部創建的位圖句柄,需要用DeleteObject
刪除位圖,釋放內存。
|
新聞熱點
疑難解答