奇怪的问题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)项目。 请给我指定。

+0

当问题发生时,您可以从第一个案例发布调用堆栈吗? – 2011-01-07 14:37:40

+1

我其实已经理解了这个问题,但是这里是调用堆栈(仅在发布模式下出错)。 > \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

+0

在这种情况下,我通常在崩溃后立即选择“调试”。假设Visual Studio以DEBUG版本打开,即使您双击可执行文件,仍然可以在崩溃后调试程序并找到问题的底部。 – 2017-04-04 08:57:14

在第一种情况下,对象被销毁(当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表明该应用程序应该停止。