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