【问题标题】:Strange problem MFC c++奇怪的问题 MFC c++
【发布时间】:2011-01-07 14:04:39
【问题描述】:

我正在 MFC /c++ 中创建一个简单的应用程序。此代码是为了在 CWinApp 类中创建一个对话框。它编译良好并且运行良好,但前提是我从 VStudio 运行它。但如果我直接运行它,运行时错误发生并且程序崩溃了。

CMyDialog dlg;
m_pMainWnd = (CWnd*)&dlg;
dlg.DoModal();

但是如果我使用下面的代码,那么一切都很好。我无法理解这种行为。

CMyDialog *dlg=new CMyDialog();
m_pMainWnd = (CWnd*)dlg;
dlg->DoModal();

在过去的一些其他 C++(非 MFC)项目中,这种事情也发生过很多次。 请告诉我这个。

【问题讨论】:

  • 当问题发生时,您能否发布第一种情况的调用堆栈?
  • 我实际上已经理解了这个问题。但是这里是调用堆栈。(仅在发布模式下出错)。 > ntdll.dll!7c911e58() [下面的帧可能不正确和/或丢失,没有为 ntdll.dll 加载符号] ntdll.dll!7c918251() ntdll.dll!7c911c76() ntdll.dll!7c911538() ntdll。 dll!7c9106eb() ntdll.dll!7c9140bb() kernel32.dll!7c801a4f() ntdll.dll!7c90e234() kernel32.dll!7c8110db() kernel32.dll!7c801a24() ...其他也不过注释大小溢出StackOverflow ...
  • 在这种情况下,我通常会在崩溃后立即选择“调试”。假设 Visual Studio 是用 DEBUG 版本打开的,即使你双击可执行文件,你仍然可以在崩溃后调试程序并找到问题的根源。

标签: c++ mfc


【解决方案1】:

在第一种情况下,对象正在被销毁(当 dlg 超出范围时)但仍由 m_pMainWnd 指向。有可能/很可能是某些原因导致使用 m_pMainWnd 并访问不再存在的对象。

将第一个例子改为:

CMyDialog dlg;
m_pMainWnd = (CWnd*)&dlg;
dlg.DoModal();
m_pMainWnd = NULL;

如果这样可以解决问题,那么您在第二种情况下侥幸逃脱的原因是该对象没有被销毁(尽管由于 m_pMainWnd 指向它,MFC 可能会在程序关闭时为您销毁它;确实,在另一种情况下,这可能是崩溃的根源)。

【讨论】:

  • 感谢 Leo,但请告诉我为什么在 VS2008 中编译时第一个案例运行良好。
  • 还有一件事我想告诉你,第一种情况在 2 天前运行良好。当我再次编译它时问题开始了。当我将 exe 文件放入 c:\ 驱动器时它运行良好,但在其他文件夹中却异常崩溃(如果是第一种情况)。
  • 如果问题是由访问一个已释放的对象引起的,那么您完全有可能之前就逃脱了它(因为指针碰巧指向不包含导致崩溃的数据的可读内存; 也许数据甚至仍然保持旧对象在被删除之前的状态)但是现在程序中的一些变化恰好使事情发生了一些变化并导致事情崩溃。不过,只是猜测。将指针设置为 NULL 是否可以解决问题?
【解决方案2】:

这两个代码块的主要区别在于,第一个,dlg 将在块的末尾被销毁,而第二个,它不会在此处的任何代码中被销毁。

考虑到程序的其余部分,在它声明的块的末尾是否仍然需要 dlg?如果是这样,您需要使用第二个块之类的东西。

另外,DoModal 也有可能调用 delete(this)(直接或间接)——在这种情况下,dlg 必须与 new 组成。

【讨论】:

  • AFAIK DoModal 不会那样做。只要我记得,我就在堆栈上创建了对话框并在 MFC 中调用了DoModal
【解决方案3】:

问题是您将m_pMainWnd 设置为在对话框关闭时将不再存在的窗口,这通常发生在对话框销毁之前,就在您关闭对话框时(当DoModal 返回)。

我通过创建一个虚拟窗口并将其用作主窗口解决了这个问题:

class CDummyWindow : public CFrameWnd
{
public:
    CDummyWindow()
    {
        Create(NULL, NULL);
    }
};

Class::InitInstance()
{
  ...
  CDummyWindow win;
  m_pMainWnd = &win;
  ...
  return FALSE;
}

请确保您return FALSE 表明应用程序应该停止。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-08
    • 2011-05-16
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2013-06-06
    相关资源
    最近更新 更多