代码之家  ›  专栏  ›  技术社区  ›  Aardvark

在模块(EXE和DLL)之间使用STL(TR1)共享ptr安全吗

  •  16
  • Aardvark  · 技术社区  · 16 年前

    我知道,在一个模块中添加新的内容,然后在另一个模块中删除它,这通常会导致VC++出现问题。不同运行时的问题。如果我没有记错的话,将模块与静态链接的运行时和/或动态链接的版本控制不匹配混合在一起都会把事情搞砸。

    因为只有一个版本的运行库知道什么是共享的ptr,所以静态链接是我唯一的危险(目前…)。我想我已经读到boost版本的共享ptr可以这样安全使用,但我使用的是Redmond版本。。。

    我试图避免在分配模块中对自由对象进行特殊调用。(或者类本身中类似“删除此项”的内容)。如果这一切看起来有点不正常,我将使用它进行单元测试。如果您曾经尝试过对现有C++代码进行单元测试,您可以理解 有时你需要保持冷静。我的内存由EXE分配,但最终将在DLL中释放(如果引用计数按我认为的方式工作)。

    5 回复  |  直到 16 年前
        1
  •  16
  •   Tim Lesher    16 年前

    释放内存是安全的,只要它来自同一个源

    您没有提到的另一个问题,但可以通过共享指针加以验证,即当对象的代码存在于DLL中并由DLL创建,但DLL之外的另一个对象最终引用了它(通过共享指针)。如果该对象在卸载DLL后被销毁(例如,如果它是模块级静态对象,或者如果DLL是由 FreeLibrary() ,共享对象的析构函数将崩溃。

    可以 被卸载,而不是让COM服务器要求卸载它们。

        2
  •  14
  •   Marc Mutz - mmutz    14 年前

    你开始明白这是多么不可思议 shared_ptr 是:)

    跨越DLL边界的安全性正是 共享ptr 设计的目的是(当然,除其他外)。

    与其他人所说的相反,在构造 共享ptr ,因为默认值已经是

    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>() );
    

    (也就是说,世上不存在所谓的 共享ptr 没有删除程序)。

    由于在删除程序上执行了类型擦除,因此 delete 那叫威尔 是DLL中的 实例化 这个 ,而不是最后一个 共享ptr 共享ptr 调用deleter将通过一个指针调用它,该指针指向原始用户放在那里的函数 ).

    将此与 auto_ptr 删去 运算符直接在其(内联)析构函数中,这意味着 删去 那个DLL的 摧毁 自动检查 使用时,会产生与删除裸指针相同的问题。

    共享ptr s甚至不需要虚拟析构函数,因为删除程序总是调用正确的析构函数,即使最后一个 超出范围是为基类实例化的。

        3
  •  7
  •   Mark Ransom    16 年前

    如果您担心的话,请使用接受deleter参数的shared_ptr构造函数的形式。删除程序可以回调分配对象的模块,以便在适当的上下文中进行删除。

    Boost的文档声称它与TR1 100%兼容,因此希望这一点没有误导性:

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

        4
  •  2
  •   dalle    16 年前

    我想它和使用中的任何一个类一样安全 std

    也就是说:如果模块使用完全相同的运行时库,以及完全相同的编译器开关和选项,那么应该是安全的。

    永远不要使用静态运行库,因为每个模块都将获得其自身的所有全局实例。

        5
  •  2
  •   Harper Shelby damiankolasa    16 年前

    关于一般主题,我看到的最好的建议是,内存应该在分配给它的相同上下文中释放。但这并不排除库传回应用程序代码应该释放的指针,因此我想说,以这种方式传递共享的ptr可能是安全的,因为这与一般情况相同。