PDA

View Full Version : live time of objects send via signals



tuli
27th November 2012, 08:41
HI,

I noticed that in our application there are a lot of memory leaks when heap-objects, taht are send around via a Qt signal are not destroyed properly.
And it dont really see a good solution here... :(



public signal:
void mysig(myob* x);


....
myob* x = new myob();
emit mysig(x);
....

When am i supposed to delete the "x" argument?

Santosh Reddy
27th November 2012, 08:55
It is not simple as it looks, there are certain things to consider.

You may at first thing that one can delete the object in the slot, but wait
1. What if no slots are connected ?
2. What if multiple slots are connected ?

Then one may think of deleting it after emiting the signal, but wait
1. What if the a connection is made between QThreads and is qued ?

If this object is QObject based object, one simple option is to connect to deleteLater() slot. (Note to make this connection as the last connection), so once all the connected slots are executed the object will delete itself.

conclusion, there may not be a standard way, it highly depends on the scope of the object which you want to achieve.

high_flyer
27th November 2012, 09:08
One way of dealing with it is making sure each object has a parent, and have that object deleted at the latest in the parents destructor.
If you parent to a QObject, you wont need to think about destruction, all QObjects destroy their children when they get destroyed.

wysota
27th November 2012, 09:51
Note to make this connection as the last connection), so once all the connected slots are executed the object will delete itself.
It doesn't have to be the last connection. deleteLater() does not delete the object, it merely posts an event to the event loop that the object is to be destroyed when the event is processed. Therefore when you call deleteLater() doesn't matter that much, you can even call it manually, without a signal, e.g.:

myob* x = new myob();
emit mysig(x);
x->deleteLater();

Note that passing such object via a signal to a different thread is forbidden anyway since QObjects are not thread-safe.

If the object is not a descendant of QObject, I'd suggest passing it by value rather than by pointer. Then regular C++ scope rules apply.

Santosh Reddy
27th November 2012, 10:12
One way of dealing with it is making sure each object has a parent, and have that object deleted at the latest in the parents destructor.
If you parent to a QObject, you wont need to think about destruction, all QObjects destroy their children when they get destroyed.

IMO, one problem with having the parent take care of deleting the child, is when the parent is long lived, there may be multiple children created and will just keep occupying the memory even if they are not used any more. I think the OP wants a solution for short lived objects.

anda_skoa
27th November 2012, 19:02
[QUOTE=tuli;233653]And it dont really see a good solution here... :(
[/CODE]

The solution is called smart pointers and the Qt class you are looking for is QSharedPointer

Cheers,
_

tuli
27th November 2012, 19:06
The solution is called smart pointers and the Qt class you are looking for is QSharedPointer
it certainly seems so! :)
Although passing by value is suitable in some cases, too.

THanks for the input, everyone, much appreciated! :)

high_flyer
28th November 2012, 09:36
IMO, one problem with having the parent take care of deleting the child, is when the parent is long lived, there may be multiple children created and will just keep occupying the memory even if they are not used any more.
One solution does not fit all.
There are many possible solutions, and the the best one is the one that best suits the case at hand, which the OP didn't fully disclose.

I think the OP wants a solution for short lived objects.
You maybe right, and maybe wrong, I don't see any indication to support either way.

Any of the offered solutions can be used, which one depends on the problem and design.