【问题标题】:Application(mfc) failing in Release build due to compiler optimization but working fine in debug build由于编译器优化,应用程序(mfc)在发布版本中失败,但在调试版本中工作正常
【发布时间】:2015-11-08 12:26:55
【问题描述】:

我面临发布版本的问题。应用程序在调试版本中工作正常,但在发布版本中,一个初始化为保存另一个类的对象的指针正在获得不同的地址分配,从而导致其值损坏。

My main application class is K32App
code in K32App.h file 
CSheetPrintManager* m_pSheetPrintManager;
CSheetPrintManager* GetSheetPrintManager() { return m_pSheetPrintManager; }

In file K32App.cpp
K32App::K32App()
{
  m_pSheetPrintManager= NULL;
} 
BOOL K32App::InitInstance()
{
  if(!m_pSheetPrintManager)
    m_pSheetPrintManager= new CSheetPrintManager();
}
K32App::~K32App()
{
  if(m_pSheetPrintManager)
    delete(m_pSheetPrintManager)
}


 In my file  CSheetPrintManager.cpp
 void CSheetPrintManager::CSheetPrintManager()
 {
   //Initialized all member variables to default values.
   Init();

 }
 void CSheetPrintManager::Init()
 {
   m_nSheetType = SheetIllegalNone;  //long
   m_sBankEntry.Empty();         //CString
   m_bHistorical = FALSE;        //BOOL
   m_bDebitDetailsSet = FALSE;  //BOOL
   m_mapRequested.RemoveAll(); // Type CMap<long,long,CString,CString&> 
 }

在应用程序启动过程中,当它到达

  if(!m_pSheetPrintManager)
    CSheetPrintManager= new CSheetPrintManager();

并尝试创建 m_pSheetPrintManager 的对象,CSheetPrintManager.cpp 中的 'this' 指针在大括号 { 处的断点处显示有效地址 (0x03768ce0),一旦我进一步进入 CSheetPrintManager.Init() , 'this' 获取不同的位置并开始指向另一个地址(0x0000000),然后进一步移动它开始指向另一个位置(0x03786ce0),然后到达m_mapRequested.RemoveAll(); 'this' 指向其他位置。 返回到主应用程序文件 C32App.cpp ,我在“自动”窗口中得到以下“m_pSheetPrintManager”CXX0030 错误“无法评估表达式”。 并且应用程序继续运行。看看当 m_pSheetPrintManager 鼠标悬停时会得到什么(不能发布图像,因为它需要 10 个声誉:) 所以链接它) studio Auto window screenshot

在调试模式下,我得到 m_pSheetPrintManager 在所有应用程序处理期间指向同一位置,并且成员始终保持正确初始化。

但在发布模式下,m_pSheetPrintManager 继续指向(自动窗口中显示的地址值)不同的位置。以及 CSheetPrintManager 类的所有成员变量,在 CSheetPrintManager 类中的每一行处理中显示不同的垃圾(未初始化)值。

如果我在发布模式下禁用 C++ 编译器优化,那么它可以正常工作,没有任何问题。

非常感谢任何帮助/指导/建议。 提前致谢。

PS:这是我在这里的第一个问题,如果遗漏了一些需要指出或正确表达的东西,请原谅。

【问题讨论】:

  • 在检查优化代码时,您在 Autos 窗口中看到的内容大多是无用的。您有两个选择:单步执行汇编代码,或者切换到 Visual Studio 2013 或更高版本并启用 /Zo (Enhance Optimized Debugging) 编译器选项。
  • @IInspectable 这是遗留代码,目前我使用的是 studio 2005。我会尝试将其移植到 2013,但不能说它会编译所有依赖项。

标签: c++ mfc


【解决方案1】:

您需要提供更多信息:CSheetPrintManager 是否封装在 dll 中?声明看起来如何?这样我就只能玩猜谜游戏了... :-/

考虑从CObject 派生,并将DECLARE DYNCREATE and IMPLEMENT_DYNCREATE 用于您的CSheetPrintManagerclass。然后,您可以在您的发布版本中使用 VERIFY()CObject::IsKindOf(),如果它是一个有效的对象。

尝试#pragma pack() 定义如何在您的类中完成填充,特别是如果您在发布版本中针对大小进行了优化并且混合了调试和发布 dll。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    相关资源
    最近更新 更多