我必须维护一个大型遗留项目,我最近从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让我怀疑这种混合可能是崩溃的原因。
我的问题是:为什么会这样?毕竟,由于从同一个地方调用new
和delete
,因此在不同的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 ++中是一个有效的关键字...)可能是在标题中定义了基类析构函数的事实导致了这个问题吗?毕竟,该标头也是主机程序已知的。
答案 0 :(得分:2)
tNew.pPolyOrig = new CInPolygon();
是的,这可以保证失败。由于在程序中使用不同的分配器,主机程序无法正确计算CInPolygon对象的大小。它使用了完全不同的std :: vector实现。它在VS2012中被重写,以利用C ++ 11。不可避免的是,使用旧版本vector的库中的代码会破坏堆。
你必须重建库,使用完全相同的编译器版本和完全相同的设置。