运算符new / delete调用不一致

时间:2010-01-20 22:06:32

标签: c++ windows dll static-libraries new-operator

我遇到一个动态链接库调用我的重载运算符删除但不是我的运算符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类。这不会引起问题,因此它让我相信它必须与链接顺序有关。

1 个答案:

答案 0 :(得分:1)

这是坏事。您实际上在DLL边界使用STL对象。这是一个很大的禁忌,并将继续给你带来麻烦。最可能的链接问题来源是可执行文件和DLL如何使用CRT。如果一个人使用静态(/ MT)而另一个是动态的(/ MD),你会看到各种各样的怪异,而重载的算子new通常是第一个出现故障的人。

如果CRT全面一致,那么它应该可以工作,但仍然不建议使用DLL,就像它是一个静态库一样。

尝试重构代码,这样就不必在DLL之外构造Type,看看是否能让它变得更好。