I have such statements:
Qt3DRender::QAttribute *attribute = // ...
const float *posBufferPtr =
reinterpret_cast<const float *>(attribute->buffer()->data().constData());
Generally, the pointer posBufferPtr
is:
However, sometimes pointer value becomes strange:
I wonder what is the meaning of <QArrayData::shared_null+24>
? I'm asking this, since when the pointer value is strange, my application gets messed up.
I fixed the bug by making sure my buffer contains data:
Qt3DRender::QGeometryRenderer *mesh = // ...
Qt3DRender::QGeometry *meshGeometry = mesh->geometry();
for (Qt3DRender::QAttribute *attribute : meshGeometry->attributes()) {
Qt3DRender::QBuffer *buf = attribute->buffer();
if (buf) {
// If buffer is empty, use data-generator to make data available
if (buf->data().isEmpty())
buf->setData(buf->dataGenerator()->operator()());
buf->setSyncData(true);
buf->setAccessType(Qt3DRender::QBuffer::AccessType::ReadWrite);
}
}
Looking in the file $QTDIR/qtbase/src/corelib/tools/qarraydata.h, we see this:
struct Q_CORE_EXPORT QArrayData
{
[...]
static const QArrayData shared_null[2];
static QArrayData *sharedNull() Q_DECL_NOTHROW { return const_cast<QArrayData*>(shared_null); }
}
... so we see that QArrayData::shared_null
is a static/singleton QArrayData
object (actually it's an array of two of them). Presumably it is being used as a sentinel-object; i.e. when another data structure such as Qt3DRender::QBuffer doesn't have a valid QArrayData
object to point to, it points to shared_null
instead, as a way to indicate that fact. Using a singleton rather than nullptr
is useful in some situations because it means that their code doesn't have to guard every dereference with a if (buffer() != NULL)
to avoid crashing when no valid QArrayData
object is available.
As for the +24
part, that indicates that your pointer is 24 bytes past the memory location where the QArrayData::shared_null
object starts at. From looking at the code in qarraydata.h
, it appears that the constData()
method calculates the pointer to return by adding a qptrdiff
offset value to its this
-pointer; so presumably that offset-value is set to 24 in this case. However, I think the precise pointer returned is probably not important, since the QArrayData::shared_null
object is unlikely to contain any usable data in any case, i.e. the array that data()
is returning is likely of length 0 and therefore the pointer shouldn't be dereferenced.
My suggestion is that before you try to use your posBufferPtr
pointer, you should call attribute->buffer()->data().size()
and verify that it's large enough for what you want to do with it, as a sanity-check. i.e. if you are trying to use the buffer as an array of float
, the guard your usage of the data with a test like if (attribute->buffer()->data().size() >= sizeof(float)*num_floats_I_expect_to_be_there)
or similar.