我知道,新-ING的东西在一个模块中,并删除 - 荷兰国际集团在另一它往往会导致VC ++的问题。问题不同的运行时间。混合staticly联的运行时和/或动态地链接的版本不匹配的两个模块,如果我记错可以拧东西了。

然而,是可以安全使用VC ++ 2008的标准:: TR1 ::跨模块shared_ptr的?

由于只有一个版本,即使知道一个shared_ptr是什么什么的运行时,静态链接是我唯一的危险(现在...)。我以为我读过的升压转换器的一个shared_ptr的版本是安全使用这样的,但我使用微软的版本...

我试图避免在分配模块中自由物体特殊的电话。 (或类似的东西在一类本身“删除”)。如果这一切似乎有点哈克,我使用这个单元测试。如果你曾经尝试过进行单元测试现有的C ++代码,你可以了解如何 创意您需要在倍。我的存储器由EXE分配的,但最终将在DLL被释放(如果基准计数的工作方式我认为它)。

有帮助吗?

解决方案

释放内存是安全的,只要它都来自同一个的内存管理的上下文来了。你已经确定了最常见的问题(不同的C ++运行时);具有单独的堆是可以运行为另一种不常见的问题。

你没有提到,但其可以通过共享指针被exascerbated另一个问题,是当在DLL存在的对象的代码和由DLL创建,但DLL之外的另一个目的与对它的引用最终(通过共享指针)。如果该对象是DLL后销毁被卸载(例如,如果它是一个模块级静态的,或者如果DLL明确FreeLibrary()卸载,共享对象的析构函数会崩溃。

这可以咬如果试图写基于DLL的,松散耦合的插件。这也是原因,COM DLL中可以决定当他们的可以的卸载,而不是让COM服务器的需求卸载它们。

其他提示

您开始看到惊人shared_ptr如何令人难以置信的是:)

跨越DLL边界是安全的正是shared_ptr被设计为(除其他事项外,当然)。

相反,别人怎么说,你甚至都不需要通过构建shared_ptrde当定制删除,因为默认已经像

template <typename T>
struct default_deleter {
    void operator()( T * t ) { delete t; }
};

shared_ptr<Foo> foo( new Bar );

等同于

shared_ptr<Foo> foo( new Bar, default_deleter<Bar>() );

(即没有这样的东西作为一个shared_ptr没有删除器)。

由于在删除器执行的类型擦除,这就是所谓的将总是是从实例化该DLL的一个delete,从未从DLL一个shared_ptr的其中最后shared_ptr超出范围(即所述shared_ptr调用删除器将调用它通过一个指向由原始shared_ptr放在那里的函数)。

比较这对auto_ptr,直接嵌入delete操作者在其(内联)的析构函数,这意味着该DLL的那delete破坏auto_ptr使用,产生同样的问题删除裸指针。

这是相同的技术,即总是在shared_ptrs举行多态类甚至不需要虚析构函数,因为缺失者总是会调用正确的析构函数,即使在最后shared_ptr走出去的范围被实例化的一个基类。

如果你担心,使用shared_ptr的构造函数有删除参数的形式。所述删除器可以调用回,使得删除发生在适当的背景下,分配的对象的模块。

升压的文档声称它是与TR1 100%兼容,所以希望没有什么误导有关此:

http://www.boost.org /doc/libs/1_37_0/libs/smart_ptr/shared_ptr.htm#constructors

我猜想它是安全的,因为在整个模块使用任何类中std

,即:如果该模块使用完全相同的运行时库,并且它应该是安全的完全相同的编译器开关和选项

不要使用静态运行时库,每个模块将在它获得自己的所有全局的实例。

我见过的一般问题的最好的建议是,内存应该在它的分配了相同的情况下被释放。这并不排除库传回该应用程序代码应该然而释放的指针,所以我说你可能是安全合格的shared_ptr以这种方式,因为它是相同的一般情况。

如果您的系统的语义意味着指针实际上是(在所有权意义上)从你的EXE转移到您的DLL,然后一个auto_ptr可能是一个更好的解决方案。但是,如果你的指针是真正共享,那么shared_ptr的可能是最好的解决方案。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top