跨dll边界的内存分配和释放

Ala*_*lan 8 c++ malloc dll memory-management stl

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

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

typedef std::set < SessionFields, 
        std::less < SessionFields >, 
        OurAllocator < SessionFields > > 
        SetSessionFields;
Run Code Online (Sandbox Code Playgroud)

在向我们的代码传递类型时,这很有效,但是我们遇到了一个问题,因为我们现在不得不在Adobe的SDK中调用一个函数来返回一个填充的向量,当它超出范围时会导致崩溃.

显然,在我的代码中最终免费的Adobe的SDK属于不同的堆中分配内存是一个问题.所以我想也许我可以做一些聪明的事情,比如以某种方式覆盖或导出SDK中使用的分配器,这样我就可以用它来清理从它们的函数返回的容器.

我也在考虑编写一个包装器或某种类型的thunking层,从而可以在我的代码和SDK之间安全地编组STL容器(虽然这听起来非常混乱).

或者,我也在考虑使用GetProcessHeaps来识别SDK 中使用的堆,并尝试释放这个堆,而不是默认堆.

有没有人就如何解决这个问题提出任何建议?

fbr*_*eto 8

具有讽刺意味的是,Adobe Source Libraries有一个adobe::capture_allocator专门针对这种DLL安全性编写的类.它的工作方式是捕获本地new,delete此时它被实例化,并在对象的生命周期中携带它们.(有关adobe::new_delete_t如何执行此操作的详细信息,请参阅此处,尤其是此处的实现.)取消分配与捕获的delete例程一起进行,保证无论您在何处删除都是正确的delete.

您可以看到Adobe Source Libraries capture_allocator中的所有version_1类型都使用过,例如adobe::any_regular_tadobe::copy_on_write.capture_allocator应该与所有STL容器类型兼容.

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


Jus*_*tin 0

您可能会尝试查看是否存在任何正式的 C++ 规则来说明当异常在一个 DLL 中引发并在另一个 DLL 中捕获然后超出范围时会发生什么情况 - 看起来非常相似。对于例外情况,我认为您需要提供带有特殊签名的复制构造函数,尽管我现在不确定它到底是什么。