奇怪的问题MFC C++
问题描述:
我在MFC/c + +中做了一个简单的应用程序。这段代码是在CWinApp类中创建一个对话框。它编译得很好,运行也很好,但是只有当我从VStudio运行它时,如果我运行它直接导致运行时错误,程序崩溃。奇怪的问题MFC C++
CMyDialog dlg;
m_pMainWnd = (CWnd*)&dlg;
dlg.DoModal();
但如果我使用下面的代码,那么一切都很好。我不明白这种行为。
CMyDialog *dlg=new CMyDialog();
m_pMainWnd = (CWnd*)dlg;
dlg->DoModal();
这种类型的事情以前也发生过很多次,对于我以前的其他一些C++(非MFC)项目。 请给我指定。
答
在第一种情况下,对象被销毁(当dlg超出范围时),但仍由m_pMainWnd指向。有可能/有可能会导致使用m_pMainWnd并访问不再存在的对象。
变化的第一个例子:
CMyDialog dlg;
m_pMainWnd = (CWnd*)&dlg;
dlg.DoModal();
m_pMainWnd = NULL;
如果解决了这个问题,你在第二种情况下逃脱了它的原因是对象没有被销毁(尽管因为m_pMainWnd指向它,MFC可能会在程序关闭时为您破坏;确实,这可能是另一种情况下崩溃的根源)。
答
这两个代码块之间的主要区别在于第一个dlg
将在块的末尾被销毁,第二个在这里的任何代码中都不会销毁。
鉴于你的程序的其余部分,dlg仍然需要在它声明的块的末尾?如果是这样,你需要使用类似第二块的东西。
或者,有可能DoModal
调用delete(this)
(直接或间接) - 在这种情况下,dlg
必须使用new
。
答
的问题是,你设置m_pMainWnd
时关闭对话框,不会存在了一个窗口,该之前通常发生对话框破坏,只是当你关闭对话框(在DoModal
返回时)。
我解决了这个问题,通过创建一个虚拟窗口,并把它作为主窗口:
class CDummyWindow : public CFrameWnd
{
public:
CDummyWindow()
{
Create(NULL, NULL);
}
};
Class::InitInstance()
{
...
CDummyWindow win;
m_pMainWnd = &win;
...
return FALSE;
}
要确保你return FALSE
表明该应用程序应该停止。
当问题发生时,您可以从第一个案例发布调用堆栈吗? – 2011-01-07 14:37:40
我其实已经理解了这个问题,但是这里是调用堆栈(仅在发布模式下出错)。 > \t NTDLL.DLL!7c911e58()\t \t [下面的帧可能是不正确的和/或缺失,没有加载ntdll.dll的符号] \t \t NTDLL.DLL!7c918251()\t \t NTDLL.DLL!7c911c76 ()\t \t ntdll.dll中!7c911538()\t \t ntdll.dll中!7c9106eb()\t \t ntdll.dll中!7c9140bb()\t KERNEL32.DLL \t!7c801a4f()\t \t ntdll.dll中!7c90e234()\t KERNEL32.DLL \t!7c8110db()\t KERNEL32.DLL \t!7c801a24()\t \t ...等也只是注释大小*的溢出 \t ... – YAHOOOOO 2011-01-07 14:44:21
在这种情况下,我通常在崩溃后立即选择“调试”。假设Visual Studio以DEBUG版本打开,即使您双击可执行文件,仍然可以在崩溃后调试程序并找到问题的底部。 – 2017-04-04 08:57:14