Reputation:
I am struggling to wrap my head around a nasty runtime error. It's a bit of code to post, but I hope it's not too much to read and too little to diagnose the issue. For some reason the unique_ptr is blowing up when I deference it and use the operator function call.
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)
);
...
}
The unique pointer blows up in FrameCollection():
Thread [1] 14303 [core: 10] (Suspended : Signal : SIGSEGV:Segmentation fault) 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
std::map, std::allocator > >::at() at stl_map.h:503 0x7ffff7bbb762 bmd2::PropertyCollection::operator at PersistentObject.cpp:140 0x7ffff7bb9137
bmd2::FrameCollection::FrameCollection() at FrameCollection.cpp:16 0x7ffff7bb5425
bmd2::Dataset::Dataset() at 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
<...more frames...>
Upvotes: 1
Views: 1626
Reputation: 9648
The issue is in your FrameCollection
class. You define a reference but never initialize it in the constructor.
class FrameCollection
{
private:
Dataset & dataset;
public:
FrameCollection();
// ...
}
FrameCollection::FrameCollection()
{
Property property (
dataset.getProperties()->operator[](PROPERTY_MAX_FRAMES)
);
//...
}
When you have a reference variable in a class, the constructor should take a reference and initiate the member in the initialization list:
class FrameCollection
{
private:
Dataset & dataset;
public:
FrameCollection( Dataset& );
// ...
}
FrameCollection::FrameCollection( Dataset& d ) :
dataset( d )
{
Property property (
dataset.getProperties()->operator[](PROPERTY_MAX_FRAMES)
);
//...
}
Upvotes: 1