CHandleMap::RemoveHandle(HANDLE h) 内断言报错

编程-鸟人-_-- 2009-03-30 02:18:22
#ifdef _DEBUG
void CHandleMap::RemoveHandle(HANDLE h)
{
// make sure the handle entry is consistent before deleting
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); // 报错定位此处
}
pTemp = LookupPermanent(h);
if (pTemp != NULL)
{
HANDLE* ph = (HANDLE*)((BYTE*)pTemp + m_nOffset); // after CObject
ASSERT(ph[0] == h);
// permanent object may have secondary handles that are different
}
// remove only from permanent map -- temporary objects are removed
// at idle in CHandleMap::DeleteTemp, always!
m_permanentMap.RemoveKey((LPVOID)h);
}
#endif

程序编译通过,运行大部分时间是正常状态的!!!可是时而会出现致命的error,但是又不是经常报错。
上网查资料,没有解释比较清楚的文章,所以在这里发布一下,向高手们求助!!!
我的工程是在WinCE下开发的,其中是有加载位图,使用了多线程,也有操纵数据库等方面操作。具体这种情况不是很清楚是哪里的问题,请问使用什么方法去跟踪一下呢?
...全文
368 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
liaochuan1234 2011-12-21
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lichunli1022 的回复:]

用GetDC()得到的DC, 必须调用ReleaseDC()
用CreateDC()创建的DC, 必须调用DeleteDC()

两者是不能混淆的.
一种典型的错误代码如下:
CDC* pDC = GetDC();
…..
//做一些无聊的事
…..

pDC->DeleteDC(); //做了错误的事

一般情况下, 上面这个代码也能够工作, 就是有时要报一点
CHa……
[/Quote]


支持下 这个解释对我很有用
mudunke775 2011-08-23
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 lichunli1022 的回复:]

用GetDC()得到的DC, 必须调用ReleaseDC()
用CreateDC()创建的DC, 必须调用DeleteDC()

两者是不能混淆的.
一种典型的错误代码如下:
CDC* pDC = GetDC();
…..
//做一些无聊的事
…..

pDC->DeleteDC(); //做了错误的事

一般情况下, 上面这个代码也能够工作, 就是有时要报一点
CHa……
[/Quote]

强烈要求对13楼加分
qq344269956 2011-05-06
  • 打赏
  • 举报
回复
刚试了一下果然是这样的
谢谢~~~~
LICHUNLI1022 2011-04-05
  • 打赏
  • 举报
回复
用GetDC()得到的DC, 必须调用ReleaseDC()
用CreateDC()创建的DC, 必须调用DeleteDC()

两者是不能混淆的.
一种典型的错误代码如下:
CDC* pDC = GetDC();
…..
//做一些无聊的事
…..

pDC->DeleteDC(); //做了错误的事

一般情况下, 上面这个代码也能够工作, 就是有时要报一点
CHandleMap::RemoveHandle(HANDLE h)异常, 跟踪进代码也看不出啥问题.
区别:
ReleaseDC()仅是释放对DC的引用
DeleteDC()是删除DC对象, 使用GetDC()的时候, 明显的这个DC不是我们自己创建的, 使用DeleteDC()的话就会将别人(通常是MFC框架)创建的DC干掉, 这样当别人要使用自己创建的DC时, 就会产生异常 了.

ReleaseDC()恰好解决这个问题, 它仅是释放一个引用, 告诉创建者DC, 我已经不用了.
LICHUNLI1022 2011-04-05
  • 打赏
  • 举报
回复
楼主最后是如何解决这个问题的
狂妄Beyond 2009-12-17
  • 打赏
  • 举报
回复
我也遇到同样的情况
airry 2009-08-19
  • 打赏
  • 举报
回复
楼主最后怎么解决的,我也遇到了这个问题
编程-鸟人-_-- 2009-04-07
  • 打赏
  • 举报
回复
再顶一下,希望有知道相关问题的大师给出更高的指导!!!
Allen_zhang 2009-04-07
  • 打赏
  • 举报
回复
窗口销毁错了吧
是不是出现了重复销毁之类的?

出现断言的时候通过堆栈找到你自己的代码看看相关的参数
cnzdgs 2009-03-31
  • 打赏
  • 举报
回复
就是程序创建一个文件,每次操作的将句柄值、操作时间等有关信息写入文件,出问题后查看文件来分析。
编程-鸟人-_-- 2009-03-31
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 cnzdgs 的回复:]
可以在Remove时把有关信息写入日志文件以便查看。
[/Quote]

请问这个怎样去实现呢?
谢谢,请高手指教!!!
cnzdgs 2009-03-30
  • 打赏
  • 举报
回复
可以在Remove时把有关信息写入日志文件以便查看。
编程-鸟人-_-- 2009-03-30
  • 打赏
  • 举报
回复
我使用线程只做大量的后台数据库初始化和部分后台计算。

1楼说的那个情况,请问用什么办法去实现跟踪!!!我每切换一个换面都会调用一次!!!
我跟踪都是直接跳到断点处,不知道,
ASSERT(ph[1] == h);  // 报错定位此处

这个前面的那个代码端在哪里??
菜牛 2009-03-30
  • 打赏
  • 举报
回复
MFC类最好不要跨线程使用,尤其不要跨线程分配和销毁。
cnzdgs 2009-03-30
  • 打赏
  • 举报
回复
调试看看是不是重复Remove了,或者句柄值不对,或是有内存越界等破坏了CHandleMap。

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧