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