我遇到一个动态链接库调用我的重载运算符删除但不是我的运算符new的问题。我的exe看起来像这样:
class A {
public:
void func() {
t = dynLib::Type::CreateObject();
}
dynLib::Type t;
};
void main() {
A a;
a.func();
}
然后我有一个静态链接的库,我有我的全局重载运算符 以及导致问题的动态链接库。基本上发生的是,dynLib :: Type类型包含一个std :: vector,它在其构造函数中添加了一个元素。所以类型看起来像这样
class Type {
public:
Type() {
v.push_back( T() );
}
std::vector< T > v;
};
当调用func()时,会创建一个新的Type实例,按值传递,然后分配给t。 operator =在工作中也通过其operator =复制std :: vector。这反过来在t中的旧std :: vector上调用deallocate,因为它已经在其构造函数中添加了一个元素。此解除分配调用最终会调用我的运算符删除。问题是,我的operator new从未被调用过,所以它在一个完全不同的内存空间中删除了一个指针(内存记录显示了这一点)。
现在,我可能只是遗漏了一些东西。由于上面的A类包含一个dynLib :: Type对象,它可能在我的operator new(来自静态库)被链接之前被构造。这甚至可能吗?我不太确定在何时调用组合的dynLib :: Type的构造函数。动态库使用默认的stl分配器,因此它不会做任何时髦的事情。
我尝试在没有动态链接库的情况下重新创建相同的情况,只需在我的exe中使用Type类。这不会引起问题,因此它让我相信它必须与链接顺序有关。
答案 0 :(得分:1)
这是坏事。您实际上在DLL边界使用STL对象。这是一个很大的禁忌,并将继续给你带来麻烦。最可能的链接问题来源是可执行文件和DLL如何使用CRT。如果一个人使用静态(/ MT)而另一个是动态的(/ MD),你会看到各种各样的怪异,而重载的算子new
通常是第一个出现故障的人。
如果CRT全面一致,那么它应该可以工作,但仍然不建议使用DLL,就像它是一个静态库一样。
尝试重构代码,这样就不必在DLL之外构造Type
,看看是否能让它变得更好。