2

我在调用我的重载运算符 delete 但不是我的 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 类。这不会导致问题,所以它让我相信它一定与链接顺序有关。

4

1 回答 1

1

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

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

尝试重构代码,这样您就不必Type在 DLL 之外进行构建,看看这是否会使它变得更好。

于 2010-01-20T23:12:55.050 回答