unique_ptr在指向对象时调用operator []()时出现分段错误

时间:2014-03-19 22:13:13

标签: c++ c++11

我正在努力绕过讨厌的运行时错误。这是一些可以发布的代码,但我希望它不是太多而无法阅读,也不能诊断问题。出于某种原因,当我遵循它并使用运算符函数调用时,unique_ptr会爆炸。

class Dataset
{
  private:
    std::unique_ptr<File> file;
    std::unique_ptr<File> & getFile() throw () { return file; }

    std::unique_ptr<Properties> properties;
    std::unique_ptr<Properties> & getProperties() throw () 
    { 
      return properties; 
    }

  ...
}

class Properties
{
  private:
    std::map<const std::string, Property> container;

  public:
    Property & operator[](const std::string & s) {
      try
      {
        return container.at(s);
      }
      catch (std::out_of_range & e)
      {
        std::stringstream ss;
        ss << "Key \"" << s << "\" does not exist in collection in 
          file " << __FILE__ << " at line " << __LINE__;
        throw Exception::KeyNotFound(ss.str(), __FILE__, __LINE__);
      }
    }
  ...
}

class FrameCollection
{
  private:
    Dataset & dataset;
  public:
    FrameCollection();
  ...
}

FrameCollection::FrameCollection()
{
  Property property (
    dataset.getProperties()->operator[](PROPERTY_MAX_FRAMES)
  );
...
}

唯一指针在FrameCollection()中爆炸:

  

线程[1] 14303 [核心:10](暂停:信号:SIGSEGV:分段错误)       std :: _ Rb_tree,std :: _ Select1st&gt;,std :: less,std :: allocator&gt; stl_tree.h中的&gt; :: _ M_begin():502 0x7ffff7ba9d72
      std :: _ Rb_tree,std :: _ Select1st&gt;,std :: less,std :: allocator&gt; &gt; :: stl_tree.h中的lower_bound():879 0x7ffff7bbbd4e
      std :: map,std :: allocator&gt; &gt; :: stl_map.h中的lower_bound():864 0x7ffff7bbba39
      std :: map,std :: allocator&gt; &gt; :: at()at stl_map.h:503 0x7ffff7bbb762       PersistentObject.cpp中的bmd2 :: PropertyCollection :: operator:140 0x7ffff7bb9137
      FrameCollection.cpp中的bmd2 :: FrameCollection :: FrameCollection():16 0x7ffff7bb5425
      数据集中的bmd2 :: Dataset :: Dataset():68 0x7ffff7ba61f9
      new_allocator.h中的__gnu_cxx :: new_allocator :: construct&gt;():120 0x7ffff7ba3b67
      在alloc_traits.h的std :: allocator_traits&gt; :: _ S_construct&gt;():254 0x7ffff7ba3977
      在alloc_traits.h的std :: allocator_traits&gt; :: construct&gt;():393 0x7ffff7ba37b7
      &lt; ...更多帧...&gt;

1 个答案:

答案 0 :(得分:1)

问题出在您的FrameCollection课程中。您定义了一个引用,但从未在构造函数中初始化它。

class FrameCollection
{
private:
    Dataset & dataset;
public:
    FrameCollection();
    // ...
}

FrameCollection::FrameCollection()
{
   Property property (
      dataset.getProperties()->operator[](PROPERTY_MAX_FRAMES)
   );
   //...
}

如果类中有引用变量,构造函数应该引用并在初始化列表中启动成员:

class FrameCollection
{
private:
    Dataset & dataset;
public:
    FrameCollection( Dataset& );
    // ...
}

FrameCollection::FrameCollection( Dataset& d ) :
    dataset( d )
{
   Property property (
      dataset.getProperties()->operator[](PROPERTY_MAX_FRAMES)
   );
   //...
}