升级到VS2012会因VC ++运行时间不同而导致崩溃?

时间:2014-02-07 08:24:19

标签: c++ visual-c++ visual-studio-2012 runtime-error msvcrt

我必须维护一个大型遗留项目,我最近从Visual Studio 2008升级到Visual Studio 2012.由于它是一个COM服务器和一个OCX控件,创建所有类型库填充等等导致了一些问题我设法解决了。但是,当我现在运行Release版本时,我经常会崩溃。

我遵循了我在SO上找到的一些建议,并且能够跟踪崩溃到下面的代码:

int Phx2Preview::ClearOvlElementList() {
    for (int i = 0; i < (int)m_vOvlElements.size(); i++) {
        P_SAFE_DELETE(m_vOvlElements[i].pPolyOrig);    // <- code crashes here
        P_SAFE_DELETE(m_vOvlElements[i].pPolyDispl);
    }
    m_vOvlElements.clear();
    m_vRefElemList.clear();
    m_pRefElemSelected = NULL;
    return PHXE_NO_ERROR;
}

P_SAFE_DELETE是一个宏,用于检查指针是否为空,并且如果它不是delete并将其设置为null。实际的矢量元素是这样创建的:

if (v1) {
    tNew.pPolyOrig = new CInPolygon();
    tNew.pPolyDispl = new CInPolygon();
    tNew.pPolyOrig->FromSafeArray(v1);
    tNew.pPolyOrig->Rotate(NULLPOINT, m_nTurnAngle*__pi/180.);
    tNew.eType = (overlayET)type;
    tNew.nImagenr = nImageNr;
    m_vOvlElements.push_back(tNew);
}

现在,问题是CInPolygon是来自外部库的类,它是使用Visual C ++ 7.1创建的。 P_SAFE_DELETE也在该库的标头中定义。从here我知道混合不同的运行时版本是,而this question让我怀疑这种混合可能是崩溃的原因。

我的问题是:为什么会这样?毕竟,由于从同一个地方调用newdelete,因此在不同的CRT之间不传递实际对象。此外,使用Visual Studio 2008编译OCX时,不会出现任何问题。这是由于纯粹的运气吗?我想基本问题也存在于那个环境中。而且,我能做些什么才能解决问题呢?切换回VS2008?


修改

正如所提出的:CInPolygon的析构函数只是

CInPolygon::~CInPolygon(void) {
  m_vPoints.clear();
}

此处m_vPoints是班级中定义的std::vector<..>。也许我应该提到CInPolygon继承自:

interface IRoi {
  virtual ~IRoi() {
    return;
  }
public:
  // other stuff
};

(甚至不知道interface在普通C ++中是一个有效的关键字...)可能是在标题中定义了基类析构函数的事实导致了这个问题吗?毕竟,该标头也是主机程序已知的。

1 个答案:

答案 0 :(得分:2)

  tNew.pPolyOrig = new CInPolygon();

是的,这可以保证失败。由于在程序中使用不同的分配器,主机程序无法正确计算CInPolygon对象的大小。它使用了完全不同的std :: vector实现。它在VS2012中被重写,以利用C ++ 11。不可避免的是,使用旧版本vector的库中的代码会破坏堆。

必须重建库,使用完全相同的编译器版本和完全相同的设置。