debug正常运行,release出错

hbrr 2005-05-04 11:26:13
错误描述:
1.degug下没有出错,release出错
2.点击一个按钮,第一次没出错,第二次出错
3.对点击按钮的动作是这么处理的:基本的处理后(简单的数据处理),告知辅助线程,辅助线程处理完后(简单的数据处理),回复主线程
4.我把辅助线程的回复取消掉,把所有的数据处理都放在主线程的按钮点击动作的处理函数中,不出错
5.错误类型:Access violation
调用堆栈:CDialog:DoModal
CWinThread::PreTranslateMessage
Cwnd::FromHandle
CWnd::AttachControlSite
...全文
432 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hbrr 2005-05-08
  • 打赏
  • 举报
回复
ON_MESSAGE要求自定义消息格式是:
afx_msg LRESULT OnMessageOwn(WPARAM wparam, PARAM param);
而我的自定义消息处理函数是这样的:void f();
原因:
当有自定义消息产生时,系统会调用自定义消息处理函数,系统想当然的认为这个函数有两个参数,分别是WPARAM,LPARAM类型。系统在调用函数时,会把两个参数压栈,而函数自身并没有参数,在release优化的情况下,在返回上一级函数时,依据的是这个函数的自动变量,参数等信息,于是这两个参数留下来了,这样产生了冲突,这样程序崩溃,这是在release下的情况。在debug下,函数执行完毕后返回上一级函数的方式:在调用一个函数时,把当前函数在堆栈中的位置保存在一个寄存器中(EBP),因此不会出现问题。
hbrr 2005-05-07
  • 打赏
  • 举报
回复
To idAnts PostMessage(AfxGetApp()->GetMainWnd()->GetSafeHwnd(), CHESSM_HPREGRETALLOWED, NULL, NULL)是这句话有点问题。

后来我在主线程中CXXXApp::PreTranslateMessage函数中截获CHESSM_HPREGRETALLOWED消息并处理,错误消除了,现在我还是没有明白原因是什么
oyljerry 2005-05-05
  • 打赏
  • 举报
回复
最好单步调试一下,看到底出错的位置在哪里
idAnts 2005-05-05
  • 打赏
  • 举报
回复
是不是PostMessage(AfxGetApp()->GetMainWnd()->GetSafeHwnd(), CHESSM_HPREGRETALLOWED, NULL, NULL);这句出错?
可能是AfxGetApp()->GetMainWnd()->GetSafeHwnd()出了问题。你再在调用堆栈里向上找找,看看是不是这句出错。
hbrr 2005-05-05
  • 打赏
  • 举报
回复
void CNEUChessDlg::OnButtonRegret() //按钮点击动作响应函数
{
//告知电脑棋手
::PostThreadMessage (m_pComputerPlayer->m_nThreadID, CHESSM_HPREGRET, NULL, NULL);
//修改状态
m_nStatus = STATUS_REGRETWAITING;//等待电脑对悔棋的应答
}

void CComputerPlayer::OnHPRegret()//辅助线程的处理,向主线程发回复
{
//后退两步
CHESSMOVE cm;
for(int i=0; i<2; i++)
{
m_moveStack.PopAMove(cm);
m_posCB[cm.From] = cm.FromChessID;
m_posCB[cm.To] = cm.ToChessID;
}
//向人类棋手发送悔棋应答
PostMessage(AfxGetApp()->GetMainWnd()->GetSafeHwnd(), CHESSM_HPREGRETALLOWED, NULL, NULL);
}

void CNEUChessDlg::OnRegretAllowed()//主线程对回复的处理
{
m_nHPMoveCount--;
if (m_nSide == RED)
{
SetGameStatus(STATUS_RED_PLAYING);
}
else
{
SetGameStatus(STATUS_BLACK_PLAYING);
}
//更新历史记录
//往前退两步(删除两条历史记录)
CHESSMOVE cm;
for(int i=0; i<2; i++)
{
m_moveStack.PopAMove (cm);
//还原cm走之间的状态
cm = GetActualCM(cm);
m_posCB[cm.From] = cm.FromChessID;
m_posCB[cm.To] = cm.ToChessID;
InvalidateRect (&GetRectByPos (cm.From), FALSE);
InvalidateRect (&GetRectByPos (cm.To), FALSE);
}
if (m_moveStack.GetMoveCount() > 0)
{
m_moveStack.PopAMove(m_cmLast);//上一步走法

m_moveStack.PushAMove(m_cmLast);//保存上一步走法到棋步栈中

cm = GetActualCM(m_cmLast);
InvalidateRect (&GetRectByPos (cm.From), FALSE);
InvalidateRect (&GetRectByPos (cm.To), FALSE);
}
else
{
m_cmLast.FromChessID = NOCHESS;
}
//更新棋步列表
m_listHistoryCMs.DeleteString (m_listHistoryCMs.GetCount()-1);
m_listHistoryCMs.DeleteString (m_listHistoryCMs.GetCount()-1);
}
friendzj 2005-05-05
  • 打赏
  • 举报
回复
建议在release 模式下调时,具体方法的话,查查历史资料,很多的~
hbrr 2005-05-04
  • 打赏
  • 举报
回复
DoModal只在CWinApp::InitInstance里调用一次
idAnts 2005-05-04
  • 打赏
  • 举报
回复
是不是一个CDialog实例反复调用DoModal()了?

16,471

社区成员

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

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

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