我正在VS2008上编写一个C ++ MFC程序,当我第一次运行程序有时时,我得到了这个“Debug Assertion Error”。当我尝试调试它时,它需要我这个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%的时间)?我该如何调试呢?
如果需要,我会提供一些代码。
谢谢!
答案 0 :(得分:3)
断言的代码是MFC的CHandleMap
类的一部分。 MFC将窗口作为CWnd
个对象处理,但Windows将它们作为HWND
句柄处理。句柄映射允许MFC将HWND
“转换”为指向表示该对象的MFC对象的指针。
断言似乎正在做的是检查当句柄的查找找到MFC对象时,MFC对象也认为它正在包装相同的句柄。
如果它们不同,那么你会得到断言。
所以看起来有些东西正在破坏句柄映射或该句柄的MFC对象,或者你正在做一些不正确的事情,导致这两个数据结构不同步。
尝试调试问题可能需要做的一些事情是确定:
pObject
指向的内容)ph[0]
和/或ph[1]
- 我不知道为什么会有2个)h
)手柄看起来像手柄值还是看起来像垃圾? pObject
是否指向看起来像MFC对象或垃圾的东西?这些事情中的任何一个看起来都相关吗?
这些问题的答案可能指向您接下来需要做的事情(可能在项目上设置一个看起来像是被删除的调试写断点)。
答案 1 :(得分:1)
几天前我得到了同样的断言,经过一些谷歌搜索, 我在这里找到了我的案例的解决方案: 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);
会解决它。
答案 2 :(得分:0)
请注意沿着这些方向的代码(来自Stroustrup的书中的内存):
c1 = (t2+t3).c_str();
(在精神上,当然可以是其他命令和表达)。临时对象在评估其封闭的完整表达式后被破坏,或者至少标准允许它们被破坏。这意味着您想要分配给c1的内容可能会,也可能不会分配给可以分配给c1的内存。编译器可能会提醒您这个问题,根据您分配的具体内容和其他情况(我不是编译器编写器)可能会也可能不会出现问题,这也可以解释为什么有时只会收到此错误消息。
所以在你的鞋子里,我会扫描我的代码以获得类似的表达并清理它们。
答案 3 :(得分:0)
当调试器中断时,将调用堆栈抬高到你的代码的第一位(如果有的话 - 希望有!)。理想情况下,它就像在代码中调用库函数错误一样简单,并且库正在使用断言捕获错误并提醒您。 (我认为任何人都无法告诉库代码有什么问题,我们需要看你的代码。)
否则,您正在进行一些棘手的调试:您正在对断言的库(看起来像MFC)做错了所以请返回并查看所有MFC代码并确保一切正确并根据文档。
答案 4 :(得分:0)
这看起来很像我今天早上的错误。这是在OnIdle()中发生的吗?
答案 5 :(得分:0)
我知道这是一篇非常古老的帖子,但希望有人可以从我的回答中得到一些帮助。
由于我的错误,我最近也遇到过类似的问题,然后我遇到了这个帖子并得到了" pac"帖子的提示。
我发现如果我使用DeleteDC()来释放从GetWindowDC()或GetDC()返回的DC,一旦CPaintDC对象实例超出范围,我将在MFC框架中得到上述断言。
CDC * pDC = GetWindowDC();
...
ReleaseDC(pDC);
您必须仅将DeleteDC()与CreateDC()API结合使用。
CDC * pDC = new CDC();
pDC->CreateDC();
....
pDC->DeleteDC();
答案 6 :(得分:0)
当我们的某些项目dll将MFC链接为静态库而将某些DLL链接为共享库时,我们遇到了这个问题(请在“项目”设置中选中“使用MFC”)