簡體   English   中英

VS2008上的“調試聲明”運行時錯誤?

[英]“Debug Assertion” Runtime Error on VS2008?

我在VS2008上編寫C ++ MFC程序, 有時在我第一次運行該程序時遇到此“調試斷言錯誤”。 當我嘗試調試它時,它將帶我到這個winhand.cpp文件,該文件不屬於我編寫的程序,因此我不確定如何調試它。

將錯誤帶到winhand.cpp中的此位置

 CObject* pTemp = LookupTemporary(h);
 if (pTemp != NULL)
 {
  // temporary objects must have correct handle values
  HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset);  // after CObject
  ASSERT(ph[0] == h || ph[0] == NULL);
  if (m_nHandles == 2)
   ASSERT(ph[1] == h);
 }

那么為什么會發生此錯誤? 為什么它有時只發生(50%的時間)? 我將如何調試呢?

如果需要,我將提供一些代碼。

謝謝!

斷言的代碼是MFC的CHandleMap類的一部分。 MFC將Windows作為CWnd對象處理,而Windows將它們作為HWND處理。 句柄映射允許MFC將HWND “轉換”為指向表示該對象的MFC對象的指針。

該斷言似乎正在做的是檢查當查找句柄時找到MFC對象時,該MFC對象也認為它包裝了相同的句柄。

如果它們不同,那么您將得到斷言。

因此,似乎是某些東西損壞了該句柄的句柄映射或MFC對象,或者您做的事情不正確,使這2個數據結構不同步。

您可能要嘗試調試問題的一些事情是確定:

  • 在查找中找到了什么MFC對象(即pObject所指向的對象)
  • MFC對象認為它包裝了什么(這是句柄ph[0]和/或ph[1] -我不確定為什么可以有兩個)
  • 句柄是什么(即h

句柄看起來像句柄值還是像垃圾一樣? pObject是否指向看起來像MFC對象或垃圾的內容? 這些東西似乎有關聯嗎?

這些問題的答案可能指向您下一步需要做的事情(也許在看起來像垃圾的項目上設置了調試寫入斷點)。

我幾天前也得到了同樣的斷言,經過谷歌搜索之后,我在這里找到了針對我的案例的解決方案: http : //forums.codeguru.com/showthread.php?216770-What-would-cause- this-assertion

就我而言,改為濫用

CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
dc->DeleteDC();

CDC* dc = GetDC();
CSize spaceSize = dc->GetTextExtent(" ");
ReleaseDC(dc);

會解決它。

從這些內容中尋找代碼(從Stroustrup的書中獲取):

c1 = (t2+t3).c_str();

(從本質上講,當然可以是其他命令和表達式)。臨時對象在包含它們的完整表達式之后,或者至少在標准允許的情況下,才將其銷毀。 這意味着您想要分配給c1的內容可能會或可能不會仍在內存中,可以在其中分配給c1。 編譯器可能會警告您該問題,並且可能會或可能不會出現此問題,具體取決於您分配的確切內容以及其他情況(我不是編譯器作者),這也將解釋為什么有時僅收到此錯誤消息。

因此,在您的鞋子中,我將掃描我的代碼以查找類似的表達式並清理它們。

當調試器中斷,調用堆棧上到你的代碼的第一位(如果有的話-希望有!)。 理想情況下,它就像代碼中錯誤地調用庫函數一樣簡單,並且庫使用斷言捕獲錯誤並警告您。 (我認為任何人都無法從代碼中找出問題所在,我們需要查看您的代碼。)

否則,您將需要進行一些棘手的調試:您正在聲明的庫(看起來像MFC)上做錯了什么,因此請返回並檢查所有MFC代碼,並確保所有內容均正確無誤並根據文檔進行。

這看起來像是我今天早上犯的一個錯誤。 這是在OnIdle()中發生的嗎?

我知道這是一篇很老的文章,但希望有人可以從我的回答中得到一些幫助。

最近,由於我的簡單錯誤,我也遇到了類似的問題,然后我偶然發現了該帖子,並從“ pac”的帖子中得到了提示。

我發現,如果我使用DeleteDC()釋放從GetWindowDC()或GetDC()返回的DC,一旦CPaintDC對象實例超出范圍,我將在MFC框架中獲得上述聲明。

CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);

您必須僅將DeleteDC()與CreateDC()API結合使用。

CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();

當我們的某些項目dll將MFC鏈接為靜態庫而將某些鏈接為共享庫時,我們遇到了這個問題(在“項目”設置中選中“使用MFC”)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM