[Interest] QueuedConnection, QByteArray, reserve, capacity

qtlist at wadefalk.se qtlist at wadefalk.se
Wed May 31 11:15:47 CEST 2017


It is my first post here, so I hope I am not violating any rules and forgive me if I am. But I don't have any mail history so I have no idea if this is a subject already being discussed. Please let me know if I'm doing something wrong.

	I discovered one thing that really surprised me when it comes to QByteArray::capacity() / reserve() and Qt::QueuedConnection. 

	First of all, i think reserve() seems not to be reliable for keeping the promise of the container's size and memory buffer integrity even under normal simple conditions. After having reserved a certain size and then modifying the actual length of the QByteArray using resize() to a size LESS or EQUAL to the size of the capacity() would unpredictably (not always) have the array to reallocate its data and again reducing the capacity. This is in my world a breakage of the semantics in the container behavior. Expecting the QByteArray::data() not to change the actual memory location is then completely false. One of the expectations of the reserve() call is to guarantee the container not to reallocate itself unless absolutely needed. 

	The only way to be sure is to access the QByteArray's internal DataPtr and on that modify it's length specifier (which of course is a wrong way of doing it, relying on internal interfaces is never right). 

	But one thing about this that is even worse. I discovered having a set capacity of a QByteArray to something and then passing that QByteArray as const reference to a signal over a QueuedConnection actually modified the capacity() ! (and indeed reallocated the array). The violation of rules in this case I feel is even worse and I suspect the moc code does something strange to make this happen. I have read the moc code is supposed to take a copy of the array and pass that copy to the other thread (this is nice of course), but how can that result in the original container in the signal emitting thread being reallocated and having its capacity modified? Here we are even talking about breakage of const promise. 

	If I'm right this is totally unexpected behavior and it should be filed as a serious bug I think. Here is a simple example. 

	 #ifndef ASYNCARRAY_H #define ASYNCARRAY_H #include  class ASyncArray : public QObject { Q_OBJECT public: explicit ASyncArray(QObject *parent = nullptr); public slots: void testSlot(const QByteArray& array); signals: void testSignal(const QByteArray& array); public slots: }; #endif // ASYNCARRAY_H #include  #include "asyncarray.h" ASyncArray::ASyncArray(QObject *parent) : QObject(parent) { connect(this, &ASyncArray::testSignal, this, &ASyncArray::testSlot, Qt::QueuedConnection); QByteArray testArray; testArray.reserve(100); testArray.resize(50); memset(testArray.data(), 0xaa, testArray.capacity()); qDebug()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20170531/d3cbf345/attachment.html>

More information about the Interest mailing list