升级到VS2012,导致由于不同的VC 运行时间而导致崩溃

Upgrade to VS2012 resulting in crash due to different VC++ runtimes?

本文关键字:VC 运行时间 崩溃 于不同 VS2012      更新时间:2023-10-16

我必须维护一个大型旧项目,我最近将其从Visual Studio 2008升级到Visual Studio 2012。由于它是COM服务器和OCX控件,因此创建了所有Typelib东西等导致了我设法解决的一些问题。但是,当我现在运行发行版时,我经常崩溃。

我遵循了一些建议,我在这里找到了一些建议,并能够将崩溃追踪到以下代码:

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 s并将其设置为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也在该库的标题中定义。从这里我知道混合不同的运行时版本是 bad ,这个问题使我怀疑这种混合可能是崩溃的负责。

我的问题是:为什么会发生?毕竟,由于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 中的有效关键字...)是否可以在标题中定义基类驱动器的事实是导致问题吗?毕竟,主机程序也知道该标头。

  tNew.pPolyOrig = new CInPolygon();

是的,这可以保证失败。简而言之,您的程序中的主机程序可能无法正确计算Cinpolygon对象的大小。它使用STD :: vector的完全不同的实现。在VS2012中,它充分利用了C 11。不可避免地,使用旧版本向量的库中的代码将损坏堆。

you 必须使用与完全相同的设置的编译器的完全相同的编译器进行重建。