【问题标题】:unique_ptr Segmentation fault when calling operator[]() on pointed to objectunique_ptr 在指向对象上调用 operator[]() 时出现分段错误
【发布时间】:2014-03-19 22:13:12
【问题描述】:

我正在努力解决一个令人讨厌的运行时错误。需要发布一些代码,但我希望阅读量不会太多,诊断问题的时间也不会太少。出于某种原因,当我尊重它并使用运算符函数调用时,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 >, std::less, std::allocator > >::_M_begin() at stl_tree.h:502 0x7ffff7ba9d72
std::_Rb_tree、std::_Select1st >、std::less、std::allocator > >::lower_bound() at stl_tree.h:879 0x7ffff7bbbd4e
std::map, std::allocator >>::lower_bound() at stl_map.h:864 0x7ffff7bbba39
stl_map.h:503 0x7ffff7bbb762 处的 std::map,std::allocator > >::at() bmd2::PropertyCollection::operator at PersistentObject.cpp:140 0x7ffff7bb9137
bmd2::FrameCollection::FrameCollection() 在 FrameCollection.cpp:16 0x7ffff7bb5425
bmd2::Dataset::Dataset() 在 Dataset.cpp:68 0x7ffff7ba61f9
__gnu_cxx::new_allocator::construct >() at new_allocator.h:120 0x7ffff7ba3b67
std::allocator_traits >::_S_construct >() at alloc_traits.h:254 0x7ffff7ba3977
std::allocator_traits >::construct >() at alloc_traits.h:393 0x7ffff7ba37b7
<...>

【问题讨论】:

  • 请提供SSCCE。不可能说这里出了什么问题——除了滥用unique_ptr(使用值代替)。
  • 不要使用异常规范,它已被弃用。请改用noexcept 说明符。
  • 必须初始化引用成员dataset。你有理由相信dataset.getProperties() 不为空?
  • 正如@aschepler 所说。这是一个链接。 stackoverflow.com/questions/5049891/…
  • 如果你们中的任何一个人会发布关于空引用的答案,那么我可以接受它作为最佳答案,因为您的线索足以帮助我找到问题所在。实际上,getProperties() 返回的是一个空对象。

标签: c++ c++11


【解决方案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)
   );
   //...
}

【讨论】:

    猜你喜欢
    • 2019-10-20
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多