我知道在一个dll中进行内存分配,然后在另一个dll中释放该内存分配会导致各种问题,尤其是在CRT方面。这些问题在导出STL容器时尤其成问题。之前(编写与我们的库链接的自定义Adobe插件时),我们曾遇到过这类问题,我们通过定义我们在所有容器中使用的分配器来解决这些问题,例如:

typedef std::vector < SessionFields,
        OurAllocator < SessionFields > >
        VectorSessionFields;

typedef std::set < SessionFields,
        std::less < SessionFields >,
        OurAllocator < SessionFields > >
        SetSessionFields;

在将类型传递到代码中或从代码传递类型时,此方法效果很好,但是我们遇到了一个问题,因为我们现在必须调用Adobe SDK中的一个函数,该函数返回填充的 vector ,该 vector 在超出范围时会导致崩溃。

显然,这是一个问题,当最终在我的代码中将其释放时,会在Adobe的SDK中分配属于不同堆的内存。因此,我在想,也许我可以做一些聪明的事情,例如以某种方式覆盖或导出其SDK中使用的分配器,以便可以使用它来清理从其函数返回的容器。

我还在看写包装器或某种形式的转换层,从而可以在我的代码和SDK之间安全地整理STL容器(尽管这听起来很困惑)。

另外,我也正在考虑使用GetProcessHeaps来识别SDK中使用的堆,并尝试释放该堆而不是默认堆。

有谁对我们如何解决这个问题有任何建议?

最佳答案

具有讽刺意味的是,Adobe Source Libraries有一个 adobe::capture_allocator 类,该类是专门为这种DLL安全性而编写的。它的工作方式是捕获实例化的本地newdelete,并在对象的生存期内随身携带它们。 (有关如何执行此操作的详细信息,请参见 adobe::new_delete_t ,尤其是实现here。)释放是通过捕获的delete例程进行的,从而确保无论您身在何处,都可以使用正确的delete进行删除。

您可以在Adobe Source Libraries中看到在整个 capture_allocator 类型中使用的version_1,例如 adobe::any_regular_t adobe::copy_on_write capture_allocator也应该与所有STL容器类型兼容。

更新:capture_allocator不符合标准,因为它保留了状态。这不应成为其可用性的主要障碍,但是,这确实意味着不能保证其使用可与符合标准的容器一起使用。

关于c++ - 跨DLL边界的内存分配和释放,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1344126/

10-13 07:06