boost序列化单例和清理程序:null引用

时间:2015-01-21 08:56:55

标签: c++ boost

使用boost(1.56)在我的程序中使用clang(3.5.1)和地址清理程序,我得到了: boost / serialization / singleton.hpp:132:13:运行时错误:引用绑定到空指针

示例是:

#include<boost/serialization/singleton.hpp> 
#include <string> 
#include <iostream> 
class Foo{ 
private: 
  std::string bar = "Hello World"; 
public: 
  void print() const{ 
    std::cout << bar << std::endl; 
  } 
}; 



int main(){ 
  boost::serialization::singleton<Foo> test; 
  test.get_const_instance().print(); 
} 

然后我这样做:

汇编

clang++ -I/boost/1_56_0/gcc-4.8.2/include/ -fsanitize=address,undefined -std=c++11 test.cpp

输出

./a.out:
boost/1_56_0/gcc-4.8.2/include/boost/serialization/singleton.hpp:132:13: runtime error: reference binding to null pointer of type 'const Foo'
Hello World

查看代码,我对类单例中引用实例的作用感到困惑。它看起来像未定义的行为。 你明白了吗?

template<class T>
bool detail::singleton_wrapper< T >::m_is_destroyed = false;

} // detail

template <class T>
class singleton : public singleton_module
{
private:
    BOOST_DLLEXPORT static T & instance;
    // include this to provoke instantiation at pre-execution time
    static void use(T const &) {}
    BOOST_DLLEXPORT static T & get_instance() {
        static detail::singleton_wrapper< T > t;
        // refer to instance, causing it to be instantiated (and
        // initialized at startup on working compilers)
        BOOST_ASSERT(! detail::singleton_wrapper< T >::m_is_destroyed);
        use(instance); // That's the line 132
        return static_cast<T &>(t);
    }
public:
    BOOST_DLLEXPORT static T & get_mutable_instance(){
        BOOST_ASSERT(! is_locked());
        return get_instance();
    }
    BOOST_DLLEXPORT static const T & get_const_instance(){
        return get_instance();
    }
    BOOST_DLLEXPORT static bool is_destroyed(){
        return detail::singleton_wrapper< T >::m_is_destroyed;
    }
};

1 个答案:

答案 0 :(得分:0)

我无法在我的Xcode 6环境中使用(地址?)清洁剂。但我确实用调试器跟踪了程序。 singleton.hpp的第132行包含行

use(instance);

其中实例的值具有(未初始化的值为零)。这可能被清洁剂视为错误,但使用(...)是一个空函数。它仅用于保证在main之前调用单例。如果不包含此内容,则编译发布可能会优化远程主调用,并且该类可能无法按预期运行。因此,我认为这是消毒剂过于热心的行为。或者,消毒剂可能被认为不够智能,无法追溯到更深层次。或者......