Strange double destructor call when using shared_ptr - c++

Finally I tracked down very strange bug, which is caused by double calling destructor. Here is the minimal code that reproduces the bug:
#include <iostream>
#include <memory>
#include <set>
class cEventSystem {
public:
cEventSystem() {
std::cout << "constructor: " << this << std::endl;
}
~cEventSystem() {
std::cout << "destructor: " << this << std::endl;
}
};
class cSubscriber {
public:
cSubscriber(cEventSystem& eventSystem) : eventSystem(eventSystem) {}
virtual ~cSubscriber() {}
virtual void onEvent() = 0;
protected:
cEventSystem& eventSystem;
};
class cTileBrowser: public cSubscriber {
public:
cTileBrowser(cEventSystem eventSystem) : cSubscriber(eventSystem) {}
void onEvent() {}
};
class cGui: public cSubscriber {
public:
cGui(cEventSystem& eventSystem) : cSubscriber(eventSystem) {
tileBrowser = std::make_shared<cTileBrowser>(eventSystem);
}
void onEvent() {}
std::shared_ptr<cTileBrowser> tileBrowser;
};
int main() {
cEventSystem eventSystem;
cGui gui(eventSystem);
}
The output is:
constructor: 0x7fffffffe67f
destructor: 0x7fffffffe2df
destructor: 0x7fffffffe67f
As you can see the first destructor is unwanted and it is called on different object which wasn't constructed at all (the adress is different), but in my real code the adress is close enough and it corrupts the containers I have in event system.
Debugging shows that it is make_shared which causes that destructor call.
What causes that unwanted destructor call and how can I get rid of it?
I use g++4.7 with c++11 flag.
The problem is that the unwanted destructor call usually (90% of times) corrupts my event system containers in my real code which causes segfaults, but rarely it doesn't corrupt it and everything works.

The CTileBrowser constructor is taking its argument by value. You're likely seeing the destruction of a temporary copy created for that constructor. Change it to a reference parameter and I bet the problem will go away.

Related

Destructor throws exception when deriving from unique_ptr

I tried to hack into unique_ptr's deleter, but without compromising construct by right value (we can't override deleter since it's associated with the right value). So I decided to try deriving from unique_ptr, here is my code.
using OStreamPtr = std::unique_ptr<std::ostream>;
class MockOStreamPtr : public OStreamPtr {
public:
MockOStreamPtr(OStreamPtr&& rhs, MockOutputSystem* sys) : OStreamPtr(std::move(rhs)), sys_(sys) {}
MockOStreamPtr(std::ostream* p, MockOutputSystem* sys) : OStreamPtr(p), sys_(sys) {}
~MockOStreamPtr() {
std::cout << "~MockOStreamPtr" << std::endl;
if (sys_) {
std::cout << get()->good() << std::endl; // this failed already
// sys_->manage(*this);
}
}
protected:
MockOutputSystem* sys_ = nullptr;
};
MSVC gives me an SEH exception on accessing ostream pointer during destruction, which I can't understand at all.
compact test case:
#include <iostream>
#include <sstream>
#include <istream>
#include <string>
#include <memory>
#include <cassert>
using namespace std;
using OStreamPtr = std::unique_ptr<std::ostream>;
class MockOutputSystem {
public:
template <typename T>
static OStreamPtr MakeStream(T&& rhs) {
return std::make_unique<T>(std::move(rhs));
}
OStreamPtr fopen(const std::string& file);
};
class MockOStreamPtr : public OStreamPtr {
public:
MockOStreamPtr(OStreamPtr&& rhs, MockOutputSystem* sys) : OStreamPtr(std::move(rhs)), sys_(sys) {}
MockOStreamPtr(std::ostream* p, MockOutputSystem* sys) : OStreamPtr(p), sys_(sys) {}
~MockOStreamPtr() {
std::cout << "~MockOStreamPtr" << std::endl;
if (sys_) {
std::cout << get()->good() << std::endl; // this failed already
// sys_->manage(*this);
}
}
protected:
MockOutputSystem* sys_ = nullptr;
};
OStreamPtr MockOutputSystem::fopen(const std::string& file) {
auto s = std::ostringstream();
s << file << ":" ;
return MockOStreamPtr(std::move(MakeStream(std::move(s))), this);
}
int main(void) {
MockOutputSystem sys;
OStreamPtr s(sys.fopen("test_file.b"));
(*s) << "hello world";
s.release(); // failed here
}
You have an inadvisable mix of strategies in play. The first thing to address is deriving from a class that was not designed as a base class – don't do that. Ask yourself: is MockOStreamPtr supposed to be a pointer to an ostream or is it supposed to have a pointer to an ostream? The former suggests inheritance, but it also suggests not introducing members (like sys_) that have nothing to do with being a pointer. The latter is closer to what you seem to want: a class that makes ostream and MockOutputSystem work together.
Option A
Make the pointer a class member, putting the output stream at the same level as the output system.
class MockOStreamPtr {
// Stuff here. I'll leave the details to you.
protected: // Sure you don't want "private" here?
OStreamPtr stream_;
MockOutputSystem* sys_ = nullptr;
};
This at least has better organization, but it can be more cumbersome since you now have two pointers to track. Also, you might run into the same problem in the destructor. Unless you spot the issue when writing a wrapper for release(). You may find your project simplified if you go with option B.
Option B
You could derive from std::ostream instead of from a pointer. This would be OK since an ostream is designed to be part of an inheritance tree. On the other hand, it is designed to be a non-leaf in that tree, so this particular inheritance would not be that useful. To have a useful inheritance, you would want to derive from something derived from ostream, perhaps derive from std::ofstream.
If ofstream is the only class that needs to be extended with knowledge of your output system, then this could work out simply. If you need to extend other classes, a template could work out almost as simply.
class MockOStream : public std::ofstream {
// Stuff here. I'll leave the details to you.
protected: // Sure you don't want "private" here?
MockOutputSystem* sys_ = nullptr; // Maybe you want a reference instead?
};
// *** OR ***
template <class S>
class Mock : public S {
// Stuff here. I'll leave the details to you. Write code as if S is ostream.
protected: // Sure you don't want "private" here?
MockOutputSystem* sys_ = nullptr; // Maybe you want a reference instead?
};
A comprehensive, robust output system should provide this sort of wrapper for you, so that you do not have to be concerned about such details. All you would need to be concerned about is avoiding object slicing. However, if MockOutputSystem::fopen must return an ofstream instead of a MockOStream, you could inject your wrapper into the construction process.
int main(void) {
MockOutputSystem sys;
// The next line is awkward; don't use it as written.
// The point is that a MockOStream's address can be used as a pointer-to-ostream.
std::unique_ptr<std::ostream> s = std::make_unique<MockOStream>(sys.fopen("test_file.b"));
s << "hello world";
s.release(); // <-- destroy the stream, using the virtual destructor
}
This better encapsulates what you want, doesn't it? When your stream is destroyed, you want something to happen based upon the associated output system. Not when the pointer is destroyed, but when the stream is destroyed.
Which leads into the specific reason your code crashed. A call to get()->good() is a memory violation when get() is null. And in your sample program, get() will be null since release() was called before the pointer's destructor. The call to release() will destroy the pointed-to object (the stream) and set the stored pointer to null. By the time the pointer's destructor is called, it is too late to do anything with that stream.

Object pointed by boost::shared_ptr in base class is never destroyed

I have a weird problem with boost shared_ptr:
class A
{
A( )
: m_myObjectPtr( new MyObject( ) )
{
}
protected:
boost::shared_ptr<MyObject> m_myObjectPtr; // MyObject class is a simple class with a constructor and destructor
};
class B : A
{
B( )
{
}
void CleanMyObject( )
{
m_myObjectPtr.reset( );
}
};
class MyObject
{
MyObject( )
{
cout << "Constructed MyObject" << endl;
}
~MyObject( )
{
cout << "Destroyed MyObject" << endl;
}
};
My problem is that the destructor of MyObject is never invoked when I call B::CleanMyObject( ). "Destroyed MyObject" is never printed.
I am seeing this on iOS with arm64 build of boost 1_57 built using https://github.com/danoli3/ofxiOSBoost/blob/master/scripts/build-libc%2B%2B.sh
Any ideas?
The obvious answer is that you have multiple shared_ptrs referring to a single object, so resetting one reduces the reference count but doesn't delete the object.
This can happen even if the shared_ptr isn't referenced outside of A and B. If you assign A or B without overloading operator= or copy A or B (e.g., pass by value, return by value) without overloading the copy constructor, then this will result.
There are several ways you could investigate.
You could check boost::shared_ptr::use_count() within your CleanMyObject to see if it's greater than 1.
If you don't want sharing and reference counting, you could replace boost::shared_ptr with std::unique_ptr or boost::scoped_ptr.
If you want to make sure you're not accidentally copying or assigning A or B, you can derive A from boost::noncopyable.
Going by #Josh Kelley's suggestion, using unique_ptr solved the problem for me.
So I diverted my attention to boost::shared_ptr to understand what is the problem. It turns out that building boost for iOS with flags BOOST_AC_USE_PTHREADS and BOOST_SP_USE_PTHREADS was the original reason for the oddity. Based on:
1) Answer by Andy Weinstein: Boost threads: in IOS, thread_info object is being destructed before the thread finishes executing
2) Weakly ordered CPU tutorial (http://preshing.com/20121019/this-is-why-they-call-it-a-weakly-ordered-cpu/)
It was clear that I should be using Spin Lock i.e., BOOST_SP_USE_SPINLOCK flag for building boost.
The problem seems to be fixed after I rebuilt boost with BOOST_SP_USE_SPINLOCK flag.
The following code illustrates a working example. It uses the shared_ptr<T> from std namespace starting in C++11, but you can substitute boost::shared_ptr<T>.
MyObject::~MyObject is invoked in the call to B::CleanMyObject as you are trying to do.
#include <memory>
#include <iostream>
using namespace std;
class MyObject
{
public:
MyObject()
{
cout << "Constructed MyObject" << endl;
}
~MyObject()
{
cout << "Destroyed MyObject" << endl;
}
};
class A
{
protected:
A()
: m_myObjectPtr(new MyObject())
{
}
std::shared_ptr<MyObject> m_myObjectPtr; // MyObject class is a simple class with a constructor and destructor
};
class B : A
{
public:
B()
{
}
void CleanMyObject()
{
m_myObjectPtr.reset();
}
};
int main() {
B b;
b.CleanMyObject();
}

How to implement factory+decorator pattern in c++11

I decided to study/translate Head First Design Patterns' Java code to C++11, and I was able to implement most of the patterns using automatic memory management thanks to smart pointers. However, I have a problem with one of the examples. Here is my code:
#include <iostream>
#include <memory>
class AbstractBase {
public:
virtual void foo() = 0;
virtual ~AbstractBase() = default;
};
class A : public AbstractBase {
public:
void foo() override { std::cout << "Class A: foo() called" << std::endl; }
};
class B : public AbstractBase {
public:
void foo() override { std::cout << "Class B: foo() called" << std::endl; }
};
class FooDecorator : public AbstractBase {
public:
FooDecorator(AbstractBase *pBase): mpBase(pBase) { }
void foo() override
{
mpBase->foo();
++mNumberOfFooCalls;
}
static int getFooCalls() { return mNumberOfFooCalls; }
private:
static int mNumberOfFooCalls;
AbstractBase *mpBase;
};
class AbstractFactory {
public:
virtual std::unique_ptr<AbstractBase> createA() = 0;
virtual std::unique_ptr<AbstractBase> createB() = 0;
virtual ~AbstractFactory() = default;
};
class CountingFactory : public AbstractFactory {
public:
std::unique_ptr<AbstractBase> createA()
{
// auto pA = new A();
// return std::unique_ptr<AbstractBase>(new FooDecorator(pA));
std::unique_ptr<AbstractBase> pA(new A());
return std::unique_ptr<AbstractBase>(new FooDecorator(pA.get()));
}
std::unique_ptr<AbstractBase> createB()
{
// auto pB = new B();
// return std::unique_ptr<AbstractBase>(new FooDecorator(pB));
std::unique_ptr<AbstractBase> pB(new B());
return std::unique_ptr<AbstractBase>(new FooDecorator(pB.get()));
}
};
int FooDecorator::mNumberOfFooCalls = 0;
int main()
{
std::unique_ptr<AbstractFactory> pFactory(new CountingFactory());
std::unique_ptr<AbstractBase> pObjA = pFactory->createA();
std::unique_ptr<AbstractBase> pObjB = pFactory->createB();
pObjA->foo();
pObjB->foo();
std::cout << "Foo called " << FooDecorator::getFooCalls()
<< " times." << std::endl;
}
What this code does essentially is; there are two derived classes A and B; and they each have a single member function that shows which one has been called. There is also a decorator called FooDecorator that adds capability to count calls made to foo().
In addition to these, there is also CountingFactory which is used to get decorated objects directly.
In the main part, using this factory, I create an instance of A and an instance of B. Then call foo() from each.
When I compile this code using clang 3.5 and run it, I do not get any errors, but the result is a bit different than expected as it calls B::foo() twice:
Class B: foo() called
Class B: foo() called
Foo called 2 times.
On the other hand, when I compile the code using gcc 4.9.2 and run it, I get the following error:
pure virtual method called
terminate called without an active exception
It looks like the problem is the unique_ptrs inside the CountingFactory. My understanding is the pointer that's used to initialize the decorated object gets freed and it leads to either undefined behavior (clang case) or termination (gcc case).
As a result, I decided to use raw pointers and added the (commented-out above) lines:
auto pA = new A();
return std::unique_ptr<AbstractBase>(new FooDecorator(pA));
auto pB = new B();
return std::unique_ptr<AbstractBase>(new FooDecorator(pB));
Doing this, things worked successfully, I got the expected output from both compilers. However, now there is a memory leak, and the allocations must be deleted.
Having almost always found a solution with smart pointers to problems like these, I am struggling to come up with the best approach to this issue. I also tried replacing unique_ptrs with shared_ptrs, but to no avail, it did not work.
Can I still get away with smart pointers following a different approach? Or do I have to manually manage the memory I allocated inside the factory (not preferred)?
As I understand, you need FooDecorator to take ownership of pBase. You can achieve this by changing
AbstractBase *mpBase;
to
std::unique_ptr<AbstractBase> mpBase;
So you create FooDecorator in CountingFactory like this:
return std::unique_ptr<AbstractBase>(new FooDecorator(new A()));
Or in C++14:
return std::make_unique<FooDecorator>(new A());
The reason for the crash is that you just assign the inner pointer via get method.
std::unique_ptr<AbstractBase> pB(new B());
return std::unique_ptr<AbstractBase>(new FooDecorator(pB.get()));
Which means that when scope ends, the memory of your inner B (or A) is gets deleted.
What you can do is call release instead.
But yeah to avoid the leak you should have a unique_ptr in your FooDecorator as well.
Live on IdeOne

Polymorphic Member Variable

I got an elegant answer yesterday for my question regarding polymorphic object members.
But now I am facing the problem that the variable isn't really behaving the way I expected it to. The following code is being used:
#include <iostream>
#include <math.h>
using std::cin;
using std::cout;
using std::endl;
class Com
{
public:
virtual void setReady()
{
cout << "Com" << endl;
}
};
class DerivedCom : public Com
{
public:
void setReady()
{
cout << "DCom" << endl;
}
void somethingElse()
{
cout << "else" << endl;
}
};
class BaseClass
{
public:
Com* com;
public:
BaseClass(Com* c = new Com) : com(c)
{
}
virtual void setReady()
{
com->setReady();
}
};
class DerivedClass : public BaseClass
{
// the call to somethingElse() won't compile if I leave out this declaration
protected:
DerivedCom* com;
public:
DerivedClass() : BaseClass(new DerivedCom)
{
}
void setReady()
{
// This line causes a segfault if I put in the declaration earlier
this->com->setReady();
// This line won't compile if I leave out the declaration earlier
this->com->somethingElse();
}
};
int main()
{
DerivedClass* inst = new DerivedClass();
inst->setReady();
return 0;
}
The problem is, that DerivedClass::com is in fact of type DerivedCom but I can't access any DerivedCom-specific methods as the compiler won't find them. If I put in an extra re-declaration DerivedCom* com, the compiler will find the methods but I get segmentation faults.
Remove that extra declaration.
If you are sure that a Com* is a DerivedCom* then you can static_cast it.
static_cast<DerivedCom*>(this->com)->somethingElse();
This will likely crash it you're wrong however. So if you are not sure then you can dynamic_cast it
DerivedCom* dcom = dynamic_cast<DerivedCom*>(this->com);
if (dcom)
dcom->somethingElse();
dynamic_cast will return NULL if the object isn't of the type you asked for.
The reason for the segmentation faults is that you arent declaring the variable again with a different type, you are actually defining a new pointer in the derived class, one that is never initialized. Thus this->com->... will access the derived class com and crash since it is an uninitialized pointer.
What you are trying to do though, is to change the type of the member pointer. You could do that by making the type of the member pointer as a template variable, as follows
template <class ComType>
class BaseClassTemplate
{
ComType* com;
...;
};
typedef BaseClassTemplate<Com> BaseClass;
class DerivedClass : public BaseClassTemplate<DerivedCom>
{
...;
};
However this makes the base class a template, so to get it as you want it, you need to make an instantiation of BaseClass<Com> to get your version of base class. You can either make it a derived class or just a typedef as i have shown.

C++ design pattern: multiple ways to load file

Summary: In search of the standard C++ design pattern for loading different files via constructor
I have a Base class with some functionality that will be used by all derived classes (e.g. Derived_A, Derived_B). The principal difference is that Derived_A and Derived_B override the load function, which is used by the constructor to load a data file (load may also be called explicitly outside the constructor).
I ran into an unexpected problem from this: the load function called by the constructor treats the class as the Base type, but when I use a default constructor and call the load function explicitly, then the virtual function table permits the intended load function to be called.
This smells like a classic problem, but I can't figure out a way to do it (and I was most recently programming in Python, which I believe, due to weak typing, would always call the intended function).
In the same vein, I'd really like Base::load to be pure virtual / abstract (only derived classes will be instantiated); however, that won't compile (I believe, because the compiler sees that the pure virtual function will be called).
Can you help?
Output:
Loading w/ constructor:
Base::load file_A
Base::load file_B Loading w/ function post construction:
Derived_A::load file_A
Derived_B::load file_B
Code:
#include <iostream>
#include <string>
class Base
{
public:
Base() {}
Base(std::string x)
{
load(x);
}
virtual void load(std::string x)
{
std::cout << "\tBase::load " << x << std::endl;
}
};
class Derived_A : public Base
{
public:
Derived_A() {}
Derived_A(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_A::load " << x << std::endl;
}
};
class Derived_B : public Base
{
public:
Derived_B() {}
Derived_B(std::string x): Base(x) {}
void virtual load(std::string x)
{
std::cout << "\tDerived_B::load " << x << std::endl;
}
};
int main()
{
// simpler code, but it doesn't behave as I hoped
std::cout << "Loading w/ constructor:" << std::endl;
Base*der_a = new Derived_A(std::string("file_A"));
Base*der_b = new Derived_B(std::string("file_B"));
// this is what I want to do
std::cout << "Loading w/ function post construction:" << std::endl;
der_a = new Derived_A;
der_a->load( std::string("file_A") );
der_b = new Derived_B;
der_b->load( std::string("file_B") );
return 0;
}
The behavior you see is well defined in C++ -- it's just not useful in this scenario because the class is not fully constructed when you call load(std::string) from Base::Base(std::string).
There are two immediate approaches:
A
You could use a container type which calls load (and perhaps holds on to the string as well). This may be more practical if you need to hold on to instances (e.g. they may have specialized error information).
class Loader
{
public:
Loader(Base* const p, const std::string& location) : d_base(p)
{
this->d_base->load(location);
}
private:
std::unique_ptr<Base>d_base;
private:
Loader(const Loader&) = delete;
Loader& operator=(const Loader&) = delete;
};
In use:
std::cout << "Loading w/ Loader:\n";
Loader l_der_a(new Derived_A, "file_A");
Loader l_der_b(new Derived_B, "file_B");
B
You could also approach it using a helper function:
class Base {
public:
template<typename T>
static void Load(const std::string& x)
{
T().load(x);
}
Base()
{
}
Base(std::string x)
{
/* load(x); << see Load(const std::string&) */
}
virtual ~Base()
{
}
virtual void load(std::string x) = 0;
};
In use:
std::cout << "Loading w/ Base::Load<T>():\n";
Derived_A::Load<Derived_A>("file_A");
Derived_B::Load<Derived_B>("file_B");
And then there are several other approaches and variations - it depends on what fits your design best. With C++, you certainly have options.
You can look up "Named Constructor Idiom".