Will the connection be disconnected in Qt automatically? - c++

From the problem here: Qt Signals and Slots object disconnect? If I first call the delete on a QObject, then I call the disconnect function like this:
MyQClass* A = new MyQClass();
connect(A,SIGNAL(A_S()),this,SLOT(B_S()));
A->deleteLater();
...
disconnect(A,SIGNAL(A_S()),this,SLOT(B_S()));
Will this cause a crash? I found it cause a crash under Qt4, but not Qt5?
Is the different Qt version doing something different? Otherwise, there might be something else wrong with my code.

Connections are disconnected automatically on object destruction. The crash probably happens because you are trying to call disconnect on an object that was destroyed. You are getting a dangling pointer A (having an address to an object that does not exist anymore). But this depends a little an what "..." is.

Related

How to free an object after all slots were executed in Qt?

I am facing an issue with Qt's signal and slot concept, as it is working asynchronously. I'm currently passing a pointer to an object which is created right before emitting a signal. I need to do this, because all receiving slots should use this object and be able to use the same state. I'm now running into problems, because I can't find a way to free the object after all the connected slots were executed. Is there an option for this?
You can use QSharedPointer. It will destruct automaically the object its holding when no one is referencing it anymore.

Why is this QObject subclass created in a different thread than its parent?

I'm running into some Qt threading issues that I don't understand, running Qt5.6 on Windows 7. Everything is installed and built using MSYS2.
I've created a Server object, which manages a Device object on behalf of remote clients. Both are subclasses of QObject. After the Server receives a client request to create a device, the Device is constructed with the Server as its parent.
But when I run the application in GDB, calling this->parent() for the Device returns a NULL pointer, indicating that this object has no parent. Furthermore, this->thread() returns a different thread from the Server object's thread. And the requisite "Cannot create children for a parent that is in a different thread" warning is printed, somewhere in the QObject constructor itself.
This is despite the Device object's constructor being passed the Server as its parent and there being no other explicitly-created threads. There are no explicitly-created QThread objects, and I'm only using the default event loop created by QCoreApplication::exec(). Furthermore, compiling and running this on either Linux or OS X confirms that the parent is set correctly and that both objects live in the same thread.
I understand why a call like setParent() or its moral equivalent will fail, to keep objects and their corresponding event loops in the same thread. But it appears that the thread affinity for the Device object is somehow already set by the time the constructor is called. But why is there more than one thread in the first place? And why only on Windows? And why would the object be created in a seemingly random thread, when it could very well use the thread of the parent that I'm passing in the constructor?
EDIT:
A couple of other things to note. I am not only not calling moveToThread() or anything like that, but there's no concurrency of any kind. This includes things like QRunnable or anything from the QtConcurrent module.
Another thing that actually solves the practical problem, but that I don't understand, is that this goes away if I compile for release. I've been using the debug build during development, which is apparently the only time the strange thread/parent behavior manifests. When I run the release build, everything works swimmingly. Is it possible this is a bug in the MSYS2 build of GDB that I'm using? Maybe there's some way in which Qt is not playing nicely with GDB (or vice versa)?
EDIT 2:
Based on a comment from #Ben, I dug around in more depth in the QObject constructor code (found here which starts on line 821. On line 826, ultimately the function QThreadData::current() is called, and this is where the threads of the parent and child first seem to differ. The Qt internal class QThreadData's static function current() (found here) seems to query thread-local storage to return the current thread's index, I think, which appears different from that of the parent's thread. I don't know enough about the Windows threading libraries to know if this is really what's going on, but after reading the pthread-based version of the code, that's my best guess.
I'm pretty far down the rabbit hole at this point, but it seems like my amended question is: Why does QThreadData::current() return a different thread from the parent? Or why has the thread-local storage containing this data changed between the time the parent was constructed and the child's constructor is called?

How to safely call disconnect in Qt?

I am using qt 4.8.
And I write something like:
Myclass* A = input_class_pointer;
...
disconnect(A,SIGNAL(A_S()),B,SLOT(B_S()));
However, sometimes when I call this, I found that the actual instance of A is already deleted somewhere else. And now the pointer A is pointing into rubbish. And by calling the disconnect, it resulted a crash.
Is there any simple way to solve this which require minimum amount of modification in the code?
I have many similar issues...
As mentioned in comments above there ways to detect whether the instance of QObject was deleted or not. One is QPointer which is a type of weak-pointer. But the problem is that we want to know when that QObject gets deleted, not after the fact. So, there is QObject::destroyed signal for that.
connect(A, destroyed(QObject*), this, onWatchObjDestroyed(QObject*));
And in your class code that watches some objects:
void MyClass::onWatchObjDestroyed(QObject* pObj)
{
// do certain disconnects for pObj, etc. if needed (?)
}

why segmentation fault occurs when using a window in a QSharedPointer?

I am developing a gui proram using Qt 4.7.4 (64 bit). I have tried to isolate the problem as follows:
I have a window: class PreferencesWindow : public QMainWindow and in another class I initialize and show it as
QSharedPointer<PreferencesWindow> pPreferencesWindow = QSharedPointer<PreferencesWindow>(new PreferencesWindow());
pPreferencesWindow->show();
it is all good, then I close the window either by pressing ESC or clicking the x button on the window. And then I call
QApplication::quit();
to terminate the whole program. It terminates but gives a segmentation fault just before terminating.
The question here is why it terminates cleanly when I use regular pointer instead of QSharedPointer and how to use QSharedPointer properly in this case?
I suspect the problem is that when you close the window, the data structure pointed to by pPreferencesWindow is deleted without the QSharedPointer's knowledge. When the QSharedPointer itself is later destroyed, it double-deletes the window, and you get the segfault.
Basically, as with all shared pointer implementations, either everybody plays, or nobody does. Since the Qt internals will never know you're using a smart pointer to manage the window, you can't use one. This is a blessing in disguise, however; it means that Qt itself takes possession of the pointer and agrees to manage it for you, so you don't need a smart pointer after all!
I am not an expert with Qt but my first thoughts would be that QMainWindow deletes itself upon destruction and the QSharedPointer object will also delete the object when it's destroyed (i.e. the object is deleted twice). If this is true you don't need to use the QSharedPointer at all.
EDIT: It looks like the QtWidget Qt::WA_DeleteOnClose flag will cause the behaviour I have described.

Deletion of objects send by signals, Ownership of objects in signals, Qt

Here, my signal declaration:
signals:
void mySignal(MyClass *);
And how I'm using it:
MyClass *myObject=new myClass();
emit mySignal(myObject);
Here comes my problem: Who is responsible for deletion of myObject:
Sender code, what if it deletes before myObject is used? Dangling Pointer
The slot connected to signal, what if there is no slot or more than one slot which is connected to the signal? Memory Leak or Dangling Pointer
How does Qt manage this situation in its build-in signals? Does it use internal reference counting?
What are your best practices?
You can connect a signal with as many slots as you want so you should make sure that none of those slots are able to do something you would not want them to do with your object:
if you decide to pass a pointer as a parameter then you will be running in the issues you describe, memory management - here nobody can to the work for you as you will have to establish a policy for dealing with allocation/deletion. To some ideas on how to address this see the Memory Management Rules in the COM world.
if you decide to pass a parameter as a reference then you don't have to worry about memory management but only about slots modifying your object in unexpected ways. The ideea is not to pass pointers unless you have to - instead use references if you can.
if you decide to pass a const reference then, depending on your connection type, QT will pass the value of the object for you (see this for some details)
avoid any problems and pass by value :)
See also this question for some thoughts about passing pointers in signals.
For your first question, use QPointer
For your second question,
If I understood clearly, even if you are sending myObject, you still have the reference myObject in the class where you are emitting the signal. Then how will it be a memory leak or a dangling pointer? You can still access the myObject from the emitted class, isn't?
Hope am clear..
Edit :
From your comments I believe you are releasing/deleting the objects in the slots. Now I assume your problem is, what if the (memory releasing) slot gets called once,twice or not called at all.
You can use QPointer for that. From the Qt documentation,
Guarded pointers (QPointer) are useful whenever you need to store a pointer to a QObject that is owned by someone else, and therefore might be destroyed while you still hold a reference to it. You can safely test the pointer for validity.
An example from the Qt documentation itself,
QPointer<QLabel> label = new QLabel;
label->setText("&Status:");
...
if (label)
label->show();
the explanation goes on like this..
If the QLabel is deleted in the meantime, the label variable will hold 0 instead of an invalid address, and the last line will never be executed. Here QLabel will be your MyClass and label is your myObject. And before using it check for Nullity.
At 1): The sender should take care. When sending the signal synchronously (instead of queued), the object is still alive when a receiver receives it. If the receiver needs to store it, only a QPointer would help, but then MyClass needs to derive from QObject, which looks wrong from the context.
Anyway, that is a general lifetime issue, not very signal/slot-specific.
Alternatives: Use a value class and send it via const reference. If MyClass can have subclasses, pass a const QSharedPointer&
About deleteLater: deleteLater() doesn't help here. It would make queued connections any safer, and for direct connections it makes no difference. The one use where deleteLater() comes into play is if the receiver needs to delete the sender. Then one should always use deleteLater(), so the sender can complete what he was doing, which would otherwise crash.
In a word (alright, function name) - deleteLater() :) All QObjects have it. It will mark the object for deletion, and this will then happen on the next event loop update.