便携式hack从weak_ptr泄漏原始指针

时间:2014-11-06 09:26:33

标签: c++ shared-ptr weak-ptr

我有一个由shared_ptr s和weak_ptr组成的对象结构,以避免圆度。 原始指针是禁止的,因为boost::serialization需要在通过对象跟踪反序列化作为序列化时间时恢复共享和弱指针。物体寿命模式很复杂(粒子模拟),但完全可以预测。每当我使用weak_ptr::lock()时,我确信指针仍然有效。通常,我使用lock().get(),因为我只需要很短的时间。

现在,lock().get()具有性能影响,因为它将增加共享计数(在lock()中),然后在不久之后递减它(临时shared_ptr被破坏)。

2002年的boost.devel post表示在开发weak_ptr时,会考虑直接访问原始指针的功能(命名为unsafe_getleak)但从来没有实现过。它的缺席迫使程序员在给定条件下使用次优接口。

现在,问题是如何模仿unsafe_get / leak,换句话说,从weak_ptr获取原始指针,对程序员的风险无效,仅阅读(不写)数据。我可以想象一些技巧,比如找出shared_ptr内的原始指针的偏移量就可以完成这项工作。

我正在使用boost::shared_ptr,但该解决方案也适用于c ++ 11' std::shared_ptr

2 个答案:

答案 0 :(得分:5)

因为你要求便携式黑客攻击。

boost's weak_ptr.hpp中找到的有趣代码部分是:

template<class T> class weak_ptr
{
  ...

public:

  ...

// Tasteless as this may seem, making all members public allows member templates
// to work in the absence of member template friends. (Matthew Langston)

#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS

private:

    template<class Y> friend class weak_ptr;
    template<class Y> friend class shared_ptr;

#endif

    element_type * px;            // contained pointer
    boost::detail::weak_count pn; // reference counter

};  // weak_ptr

这意味着如果使用BOOST_NO_MEMBER_TEMPLATE_FRIENDS选项编译boost,您将公开访问weak_ptr的成员px,该成员似乎是元素类型的原始指针。

答案 1 :(得分:3)

我建议您只需同时使用weak_ptr和原始指针,并在知道安全时直接使用原始指针作为优化。如果您愿意,可以将weak_ptr和关联的原始指针包装在具有unsafe_get的类中。