QSharedPointer is null with strongref existent
-
UaClient and PlcList both have a
QList<QSharedPointer<PlcAddress>>
. PlcList passes a Reference to UaClient of that list, and then UaClient does some things with that list. Test crashes when calling UaClient dtor bc QSharedPointer dtor can not free that memory.1 QtSharedPointer::CustomDeleter<PlcAddress,QtSharedPointer::NormalDeleter>::execute qsharedpointer_impl.h 158 0x7ff66620a027 2 QtSharedPointer::ExternalRefCountWithCustomDeleter<PlcAddress,QtSharedPointer::NormalDeleter>::deleter qsharedpointer_impl.h 180 0x7ff6661e9bc5 3 QtSharedPointer::ExternalRefCountData::destroy qsharedpointer_impl.h 114 0x7ff6661e6c11 4 QSharedPointer<PlcAddress>::deref qsharedpointer_impl.h 458 0x7ff6661e6896 5 QSharedPointer<PlcAddress>::deref qsharedpointer_impl.h 451 0x7ff6661e6848 6 QSharedPointer<PlcAddress>::~QSharedPointer<PlcAddress> qsharedpointer_impl.h 281 0x7ff6661e21b4 7 QSharedPointer<PlcAddress>::`scalar deleting destructor' tst_Plc 0x7ff6661e3238 8 std::_Destroy_in_place<QSharedPointer<PlcAddress>> xmemory 310 0x7ff6661dd786 9 std::_Destroy_range<QSharedPointer<PlcAddress> *,QSharedPointer<PlcAddress> *> xmemory 1098 0x7ff6661dd8f5 10 std::destroy<QSharedPointer<PlcAddress> *> memory 574 0x7ff6661de82b 11 QtPrivate::QGenericArrayOps<QSharedPointer<PlcAddress>>::destroyAll qarraydataops.h 398 0x7ff6661e6ebb 12 QArrayDataPointer<QSharedPointer<PlcAddress>>::~QArrayDataPointer<QSharedPointer<PlcAddress>> qarraydatapointer.h 104 0x7ff6661e1fbd 13 QList<QSharedPointer<PlcAddress>>::~QList<QSharedPointer<PlcAddress>> tst_Plc 0x7ff6661e2127 14 UaClient::~UaClient UaClient.cpp 10 0x7ff6661fd066 15 PlcList::~PlcList PlcList.h 21 0x7ff6661e24b2 16 TestPlc::testUaClientMonitoringAndListModel tst_Plc.cpp 158 0x7ff6661db80e 17 TestPlc::qt_static_metacall tst_Plc.moc 196 0x7ff6661da54e 18 QMetaMethodInvoker::invokeImpl qmetaobject.cpp 2713 0x7ffeb56ae03e 19 QMetaMethod::invokeImpl qmetaobject.cpp 2551 0x7ffeb56aa383 20 QMetaMethod::invoke<> qmetaobject.h 150 0x7fff0ca8dd77 ... <More>
Im running this in a test. After dtor of PlcList gets called at the end of the test the first two entries of the
QList<QSharedPointer<PlcAddress>>
in UaClient are null.
What I dont understand is, how can there still be a strongref to that pointer but it seems to be freed in the PlcList dtor.
~PlcList() = default;
Is there something going on when using the default dtor? -
PlcList.h
.. QList<QSharedPointer<PlcAddress>> m_addressList; ..
PlcList.cpp
PlcList::~PlcList() { m_addressList.clear(); } init(){ .. m_uaClient.setAddressList(m_addressList); .. }
UaClient.cpp
void UaClient::setAddressList(const QList<QSharedPointer<PlcAddress>>& list) { for (const QSharedPointer<PlcAddress>& plcAddress : list) { m_addressList.append(plcAddress); } }
That is basically everthing in regards to the communication betweend these two classes. When I explicitly clear the list, as I just posted in this answer, I can see that after the clear statement the strongref count goes down to 1, as expected. The next step in the stack trace is directly in the UaClient dtor, and there the pointer is suddenly null.
-
@Redman said in QSharedPointer is null with strongref existent:
m_addressList
How is this defined in both classes? Do you explicitly delete the pointers somewhere?
-
@Christian-Ehrlicher Nope. But I found the solution just now. Doing
emit mysignal(QSharedPointer<MyClass>(this))
is not good. Through this signal,
m_addressList
got populated.
Unfortunately I can not understand why this results in this strange behaviour -
@Redman said in QSharedPointer is null with strongref existent:
Unfortunately I can not understand why this results in this strange behaviour
Because you delete this instance somewhere else - e.g. because it is derived from QObject and has a parent.
-
@Christian-Ehrlicher Please elaborate how emitting a newly created SharedPointer of
this
and then appending that to a List leads to that error. As I said in my previous answer, after removing that line everything works fine when shutting down the application. -
Since I don't know your code I can't say more. You are doing a double delete. We can't see where. So please provide a minimal compileable example of you want help.