On Wednesday, 31 May 2017 02:15:47 PDT qtl...@wadefalk.se wrote: > 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.
It you shrink too much, then it releases the memory. (where "too much" may be "less than half", I'd have to check the sources) > 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. The signal-slot system treats const references the same as passing by value. So when you have a queued connection, the system will actually create a copy behind your back and queue that to the other thread. Please note that this needs to happen, since the slot is called asynchronously from the emission: this is the only way to guarantee that the reference that the slot gets is valid, with no data race issues. That is also why you cannot pass non-const references via queued connections. You can pass pointers (the pointer is copied and the pointed object is your problem). I *think* we wrote the optimisation that a BlockingQueuedConnection does not copy, but again I'd have to check the sources. > 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. Not a bug. This is expected and required behaviour. > > #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() Line breaks anywhere, please? Anyway, not relevant. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel Open Source Technology Center _______________________________________________ Interest mailing list Interest@qt-project.org http://lists.qt-project.org/mailman/listinfo/interest