BOOST shared pointer causes redundant reference delete - c++

I have the following app structure :
/// CLASS VIEW3D.h
class View3D;
typedef boost::shared_ptr<View3D> ViewSP;
class View3D
{
public:
View3D(void);
};
/// CLASS SCREENQUAD.h
class ScreenQuad
{
public:
ScreenQuad(ViewSP view);
~ScreenQuad(void);
protected:
ViewSP _viewSP;
};
/// CLASS VIEW3D.cpp
View3D::Init(ViewSP view)
{
_screenQuadSP=new ScreenQuad(view);
}
/// CLASS SCREENQUAD.cpp
ScreenQuad::ScreenQuad(ViewSP view):
_viewSP(view)
{
assert(_viewSP);
}
Now, I pass a reference of class A into class B in the form of shared pointer and keep it in a global variable A_SP. When the app shots down I am getting this:
HEAP: Free Heap block 2837920 modified at 2837b5c after it was freed
After debugging the execution I found that after the class A destructor has been called it gets called again when the destructor of class B is executed.So my guess is that the boost tries to free the memory at the address of the pointer encapsulated in _A_ref.
Just to note: the order of destruction is A class first, then B class.
How do I get around it? Shouldn't shared_ptr keep the ref count and not to trigger destructor of the object which has already been released?

Your code is still too incomplete the show the problem, but I can think of a few common causes for such an error.
You explicitly delete your View3D instance somewhere. Don't do that, the shared_ptr will. If you no longer need the object, you can call ptr.reset(), which will decrease its reference count and delete it if appropriate. (This happens automatically when a shared_ptr is destroyed, e.g. in your ScreenQuad destructor; in that case there's no need to do it explicitly.)
You accidentally created multiple reference counters for the same object. There should be only one spot where you create a shared_ptrfrom a View3D* raw pointer, namely at the same place where the object is created. Everywhere else, you have to create your shared pointers from other shared (or weak) pointers. Otherwise you'll end up with multiple reference counters, and each of these will eventually try to delete the object, even if it has been freed already.
You created a shared_ptr to an object on the stack. Essentially, that's the same problem as calling delete on a stack-allocated object.
This might help you find the error yourself, otherwise you really need to post more code – as far as I can see nothing of this happens in the snippets you showed so far.

Related

Is it ok practice to have a unique pointer pointed at a shared pointer?

I'm having some difficulties trying to solve a pointer problem in C++.
Let's say I have class called MyClass. Inside this class, there is a shared pointer that points at some outside resource called MyResource. Now let's also say that within MyClass, there are a few instances of an object called MyObject. Each instance of MyObject also needs to reference MyResource. Let's assume this class doesn't do anything except contain these components I've just mentioned
class MyClass
{
shared_ptr<MyResource> m_p_my_resource;
MyObject m_my_object1;
MyObject m_my_object2;
MyObject m_my_object3;
}
How I had previously (tried to) implemented this, I would create a shared pointer and give it to m_p_my_resource. I would then give m_p_my_resource to each instance of MyObject. I assumed that whenever m_p_my_resource changed to point at a new MyResource, each of MyObjects would also point at the new resource.
However, I realize what I did wasn't correct. When I would change m_p_my_resource, this would indeed be pointing at a new resource. However, each instance of MyObject would still be pointing at the original MyResource.
Now I'm trying to think of methods on how to actually implement what I was originally trying to do: be able to change m_p_my_resource and have each instance also point at the new resource.
One way to solve this is to update each instance of MyObject whenever m_p_my_resource changes. I would likely need to have a setResource method that would update m_p_my_resource and then iterate through each instance of MyObject.
An alternative solution is to have each instance of MyObject contain a pointer to a pointer of MyResource. So if each MyObject was pointing at a pointer to the resource instead of the resource itself, I could change m_p_my_resource and each object would also be able to determine the new resource.
While this second method would probably work in the class example I listed above, it's not elegant for instances of MyObject not contained within a class. As in, if I simply created a MyObject on the stack, I would rather have it point directly at the resource instead of having it point at some intermediate pointer that is pointing to the resource...
So I'm trying to determine the best method for implementing what I describe. I'm still relatively new to smart pointers and am curious if what I'm trying to do is stupid, or if there a better/obvious alternative solution.
If it is true that the lifetime of the MyObjects are identical to the lifetime of MyClass then each instance of MyObject can instead hold an reference or pointer to the shared_ptr<...> to achieve what you want.
class MyClass {
public:
shared_ptr<MyResource> resource;
MyObject obj1 { resource };
MyObject obj2 { resource };
};
class MyObject {
public:
shared_ptr<MyResource>& resource;
void foo() {
resource->do_something(); // works transparently
}
}
And you can safely change the contents of MyClass::resource:
void bar(MyClass& myClass) {
myClass.resource.reset(new MyResource());
assert(myClass.resource.get() == myClass.ob1.resource.get());
assert(myClass.resource.get() == myClass.ob1.resource.get());
}
Double-pointers are exactly the right technique to solve your problem.
However, I'm a little confused why you would want a unique_ptr to a shared_ptr like you say in your title. You don't mention unique_ptrs anywhere in the body of your question, and it seems like what you really want is a shared_ptr<unique_ptr<MyResource>>, not a unique_ptr<shared_ptr<MyResource>>.

How to use smart pointers with setUserData(void*)?

is it possible to use c++11 smart pointers with nodes user data? has anyone tried it before?
node->setUserData(void* usrData);
node->getUserData();
Solved:
i figured a way to store objects in a Node without having to delete theme manually(gets automatically deleted when the Node is destroyed) and it might not be the best solution but it is a solution nevertheless, it involves inheriting from cocos2d::Ref class and using nodes setUserObject(Ref* ptr)!
this is how i made it happen:
1)- make a class/struct that inherits from cocos2d::Ref class.
2)- fill it with your custom properties and methods.
3)- make sure the object calls autorelease().
struct Box : public cocos2d::Ref
{
// some properties here
Box() {
//autorelease means let other Nodes retain and release this object.
//if you don't call autorelease then the object destructor won't get called which means in turn object memory is not released.
this->autorelease();
}
~Box() {
//just to check if the object destructor is called or not.
log("=========================");
log("Box is destroyed");
log("=========================");
}
};
4)- make an object instance and put its pointer in any Node UserObject like this:
auto box = new Box;
this->setUserObject(box);// am putting it in the Layer UserObject
now the box object will be destroyed automatically whenever the Layer/Node is destroyed (no delete is needed)
PS: you should properly exit the cocos2d-x app in order for the nodes(Node, Layer, Scene) destructors to be called so can nodes children be destructed properly(children destructors are called) ... just press the back button if your in an emulator or use a close button that calls Director::end().
This was a comment, but got too long.
I wouldn't see it as hopeless as #Joachim Pileborg does in the comments (although his points are true in principle). The only thing you have to assume is that setUserData is only observing, i.e. it performs no memory-related actions and particularly no delete.
You can then either simply use a smart pointer "outside",
auto ptr = std::make_unique<some_object>();
node->setUserData(ptr.get());
Now, if the program then exits in a proper way, at least you don't have to manually delete ptr. But, as mentioned by Joachim, of course you have to make sure that ptr lives as long as it is might be used inside node.
Alternatively, you can write small wrapper around the node class which contains a shared_ptr<void> ptr variable and which offers a setUserData(shared_ptr<void>) method. If this method is invoked, it first copies the shared pointer and internally calls node->setUserData(ptr.get()) method. Then the underlying object is guaranteed to stay alive.

object that may die anytime pointed by several objects

In my game there are a lot of object of class Foo that interact with each other. A static method of the class Foo update all the object, using a container in order to track the created objects.
My problem is that a Foo object could kill another object, other instances of Foo don't know about this horrible event and they could use the dead object (deleted) anyway, thus giving an error.
I have some ideas to avoid pointer to deleted object, but I don't think they are suitable.
1) A kind of smart pointer that checks for null object.
probably this is the worse idea, I didn't not see anywhere something like this. I could create a pointer which, when delete is called, delete the pointed Foo object and then gives false when converted to Boolean (so it's possible to know if it's possible to call method on it).
2) Each Foo object doesn't track other object with a pointer but with an ID.
then the object gets a pointer to another Foo object with a static method of Foo class ( as I said Foo class has a container that tracks all the instances).
It would work also in a multithreaded environment with simple modifications, but it may be really expansive, each object searches another one in the container during each frame.
3) Each Foo object tracks objects that have a pointer to it.
The object, when killed (deleted), calls a method of the other objects. Then these object erase any pointer to the deleted object. There are other classes, too. So this isn't really object oriented.
I actually think there is an easy solution that I can't find.
Essentially all these objects share ownership of this killable object. The strongest assurance you can give them is that it won't be deleted out from under them. You can accomplish that by giving each one a boost::shared_ptr. Notifying all the objects when it dies would allow them to drop their reference. You can use boost::signals to accomplish that. I would try for this first.
If you can't do that, then you could have them store a boost::weak_ptr and when their call to boost::weak_ptr::lock failed, they would know it was dead.

c++ Dependency Injection: Object lifetimes?

I'm coming from C# and trying to translate some of my practices into C++. I've used dependency injection in various places throughout my code using raw pointers. Then I decide to replace the raw pointers with std::shared_ptr's. As part of that process it was suggested that I consider using stack allocated automatic variables rather than dynamically allocating them (see this question although that question was in the context of unique_ptr so maybe that is different).
I believe the below example shows the use of automatic variables.
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
~MyClass()
{
appService_.Destroy(something);
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
In the above example, when customAppservice and myclass go out of scope how do I know which will be destroyed first? If customAppService is destroyed first than the MyClass destructor will fail. Is this a good reason to use shared_ptr instead in this scenario or is there a clean way around this?
UPDATE
ApplicationService is a class that is a wrapper around global functions needed to interact with a 3rd party library that my code uses. I have this class as I believe it's the standard way to support unit testing and stubbing/mocking of free standing functions. This class simply delegates calls to the corresponding global functions. The call appService_.Destroy(something); is actually destroying an object used by each specific instance of MyClass not destroying anything do with the Application class itself.
The answer is: you don't need to know, as your design is broken, anyway.
First, a Destroy sounds like a bad idea, furthermore if called in an object that is not responsible for the destruction of the other object. The code from the Destroy method belongs into ApplicationService's destructor (which is hopefully virtual, although in this case it doesn't actually need to), which in contrast to C# gets called at a perfectly determined point in time.
Once you've done this, you will (hopefully) realize, that it is not the responsibility of MyClass to destroy the appService_, as it does not own it. It is the responsibility of the ConsumerClass (or rather the DoSomething method), which really manages the actual service and which does actually destroy it automatically once you've moved Destroy's code into the destructor. Isn't it nice how RAII does make happen everything in a clean and automatic way?
class MyClass
{
public:
MyClass(ApplicationService& app): appService_(app)
{
}
private:
ApplicationService& appService_;
}
class ConsumerClass
{
DoSomething()
{
CustomApplicationService customAppService;
MyClass myclass(customAppService);
myclass...
}
}
class ApplicationService
{
public:
virtual ~ApplicationService()
{
//code from former Destroy method
}
}
class CustomApplicationService
{
public:
virtual ~CustomApplicationService()
{
//code from former Destroy method
}
}
This is IMHO the perfect clean C++ way around it and the problem is definitely not a reason to spam shared_ptrs. Even if you really need a dedicated Destroy method and cannot move the code into the destructor (which I would take as a motivation for overthinking the design), then you would still call Destroy from DoSomething as again, MyClass is not responsible for destroying the appService_.
EDIT: According to you update (and my stupid overlooking of the something argument), your design seems indeed quite correct (at least if you cannot mess with changing the ApplicationService), sorry.
Allthough class members should get destroyed in reverse order of construction, I'm not sure this also holds for local automatic variables. What you could do to make sure the destructors get called in a defined order is introduce nested scopes using simple blocks:
void DoSomething()
{
CustomApplicationService customAppService;
{
MyClass myclass(customAppService);
myclass...
} // myclass destroyed
} // customAppService destroyed
Of course there is still completely no need to use dynamic allocation, let aside shared_ptrs. Although the nested blocks blow the code a bit, it is nothing against the ugliness of dynamic allocation applied in a non-dynamic way and without reason and it at least "looks nice in a semantic way" with customAppService's declaration on top of the block ;)
In C++, objects, in general, are destroyed in the order that is exact opposite of the order they were created in.
Based on your example, MyClass will be destroyed before CustomApplicationService
The exception is when a destructor is called explicitly. However, I don't think you should concern yourself with this exception at this stage.
Another subtlety is called static initialization order fiasco . However, this does not apply to automatic (stack) variables.
Edit:
From C++2003 - looked for 'reverse order'
6.6.0.2
On exit from a scope (however accomplished), destructors (12.4) are called for all
constructed objects with automatic storage duration (3.7.2) (named objects or
temporaries) that are declared in that scope, in the reverse order of their
declaration. ... [Note: However, the program can be terminated (by calling exit()
or abort()(18.3), for example) without destroying class objects with automatic
storage duration. ]

Question about deleting a pointer. Which class should it be deleted from?

I have two four classes:
MainClass (class where things start)
XmlReader (class used to parse an xml file)
SerialPortSettings (holds info about the serial port read from the xml-file, e.g. baud rate, comport etc)
SerialPortListener (takes a reference to a SerialPortSettings object in its constructor)
MainClass has a method to read things from an xml-file.
In this method, it first creates an instance of XmlReader and gives it an xml-file as a constructor parameter. This xmlReader does only need to exist within this method:
XmlReader xmlReader (xmlFile);
The xmlReader parsers the xmlFile. MainClass gets access the xml-stuff by calling get-methods in XmlReader. So far everything is good.
However, one of the methods XmlReader offers, is a method which creates an object of type SerialPortSettings based on the information read from the xml-file:
SerialPortSettings* XmlReader::getSerialPortSettings() {
.... // reading stuff from xml file
return new SerialPortSettings(baudRate, dataBits, comport);
}
This method is called from MainClass and the return value is stored in a pointer:
SerialPortSettings* settings = xmlReader.getSerialPortSettings();
The next thing the MainClass does is to create a SerialPortListener (which is a member-variable that has to exist until MainClass is exited). SerialPortListener takes a reference to a SerialPortSettings in it's constructor:
m_serialPortListener = new SerialPortListener(*settings);
Hence SerialPortSettings also has to exist until MainClass exits, therefore I have created this as a pointer.
So here is the clue:
In the SerialPortListener destructor I tried to delete the SerialPortSettings-object:
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
Then in the MainClass destructor I deleted the SerialPortListener-object:
MainClass::~MainClass() {
delete m_serialPortListener;
}
This fails. I get an error saying that I deleted something twice in the main-class:
*** glibc detected *** ./ioserver: double free or corruption (out): 0x00860d80 ***
When I remove the delete &m_settings from SerialPortListener, it works fine.
But when should pointer be deleted? What is the correct thing to do? I really want my xml-reader to create the SerialPortSettings - object, insted of returning all of the info (baud rate, comport etc) to MainClass and create the SerialPortSettings object itself.
A good solution is to simply let xmlReader::getSerialPortSettings return a SerialPortSettings by value.
Let the compiler do the optimization.
But where you do need to handle pointer lifetimes, do use smart pointers, such as std::auto_ptr or boost::shared_ptr. The key idea is to define ownership. The owner (which in the case of boost::shared_ptr is the collection of smart pointers referring to the object) is responsible for deleting – no-one else.
Cheers & hth.,
The pointer should be deleted at the end of MainClass.
It makes no sense (to me, at least) to use delete on a reference.
It would be way cleaner to not have the XML reader create new objects; treat SerialPortSettings as a "dumb" container, and just pass in a reference to fill in with data from the XML:
XmlReader::getSerialPortSettings(SerialPortSettings& settings);
the actual instance can then be a local variable in the main program, and be passed (by const reference, this time) to the serial port when it's created:
SerialPortSettings portSettings;
m_xmlReader->getSerialPortSettings(portSettings);
m_serialPort = new SerialPort(portSettings);
the life time of the settings instance is then naturally the same as the scope it's in, since it's just a local variable.
If the method in the main class that reads XML needs to exit before the serial port goes out of scope, you could make the settings a member variable of the main class, instead.
What is the datatype of m_settings? Is it a SerialPortSettings* or a SerialPortSettings? If the latter, you can't delete it like that anyway, as it's allocated on the stack. If it's the former (a pointer), you do not need the reference operator. Simply write delete m_settings;
A simple typo in your delete:
delete &m_settings;
should be:
delete m_settings;
For any pointer you should decide who owns the pointer, and that should be who deletes it.
Or you can use a smart pointer such as shared_ptr and eliminate the problem altogether.
SerialPortListener::~SerialPortListener() {
delete &m_settings;
}
That block looks quite weird. Are you sure you aren't trying to delete value by reference? Cause C++ does it automatically when you delete the class, so your delete is really trying to delete twice.
OK, first of all, you're missing the truly important bit of information which is HOW is SerialPortListener::m_settings being stored. Because of the error you're getting, I'm guessing you're actually storing a copy of it, which means: I bet you have something like this:
class SerialPortListener {
SerialPortSettings m_settings;
SerialPortListener(SerialPortSettings set) {
m_settings = set;
}
}
if it's something similar to this, then the listener is saving a copy of the object in it's own memory, and deleting it doesn't make sense, since it's not a pointer. Rule of thumb, never do delete &anything until you know what you're doing and realize you really need to.
In terms of "correctness", the pointer should be freed by the main class, since it was who created it. Or if you don't have any use for it in the main class, and want the listener to delete it, save a pointer instead of an object or reference in the listener.
I ended up making m_serialPortSettings a pointer in SerialPortListener, and deleting it from there.