由于编译器优化,Application(mfc)在Release版本中失败,但在调试版本中运行良好

时间:2015-11-08 12:26:55

标签: c++ mfc

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

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错误'表达式无法在自动窗口中评估“。 和appplication继续运行。看看当悬停m_pSheetPrintManager鼠标时会得到什么(不能发布图片,因为它需要10个声誉:)所以链接它) studio Auto window screenshot

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

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

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

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

PS:这是我在这里提出的第一个问题,请原谅如果遗漏某些内容或正确表达的话。

1 个答案:

答案 0 :(得分:0)

您需要提供更多信息:CSheetPrintManager是否包含在dll中?宣言如何?这样我只能玩猜谜游戏......: - /

考虑从CObject派生并使用DECLARE DYNCREATE and IMPLEMENT_DYNCREATE为您的CSheetPrintManager课程。如果使用VERIFY() IsKindOf(),您可以在发布版本CObject::中使用JOIN

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