最近,一直遇到assert failed錯誤,這個要在debug下才會有,根據彈出的對話方塊可以找到相應的源檔案,找到對應的assert,比如我的是wingdi.cpp,line1194
BOOL CGdiObject::Attach(HGDIOBJ hObject){ASSERT(m_hObject == NULL); // only attach once, detach on destroyif (hObject == NULL)return FALSE;CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not existASSERT(pMap != NULL);pMap->SetPermanent(m_hObject = hObject, this);return TRUE;}
第一個assert即是1194行。
找到問題所在,可以在此處設一斷點,然後出現錯誤時,通過查看堆棧定位問題源頭。
一開始有一個原因,這個不具代表性,見:
http://topic.csdn.net/u/20121001/23/bda454b2-7997-4fbe-b888-047cd69077be.html?seed=2025379092&r=79807886#r_79807886
後來,又遇到一個原因是CFont的,create Font之後,沒有刪除,而且是在OnPaint中建立的,所以,視窗重繪是,又會調用建立,而建立Font又會調用上面的Attach(這個可以藉助call stack看清楚,這個函數是被誰調用的,call stack在memory上右鍵即可調出),而第一個assert認為第一次應該是NULL,而我沒有刪除Font,所以不是NULL,所以出現assert
failed。
其實這個歸根到底,是自己操作不規範,想偷懶,建立了就不管了,而且DC選擇Font完後,要從DC中選擇出,即選擇原來的Font。DC選擇出,Font刪除,在MSDN中清楚的寫著,自己偷懶,所以導致調試的這麼費勁!!!
When you finish with the CFont object created by the
CreatePointFont method, first select the font out of the device context, then delete theCFont object.
m_FontB.CreatePointFont(250, _T("Arial"), NULL);。。。CFont *def_font = dc.SelectObject(&m_FontM);。。。dc.SelectObject(def_font);
另外select的時候要傳遞指標,這個一開始也沒注意。