访问Qt3DRender::QBuffer的数据时数据指针为<QArrayData::shared_null+24>

Data pointer is <QArrayData::shared_null+24> when accessing data of Qt3DRender::QBuffer

我有这样的说法:

Qt3DRender::QAttribute *attribute = // ...

const float *posBufferPtr =
                reinterpret_cast<const float *>(attribute->buffer()->data().constData());

一般指针posBufferPtr是:

但是,有时指针值会变得奇怪:

不知<QArrayData::shared_null+24>是什么意思?我在问这个,因为当指针值很奇怪时,我的应用程序就会一团糟。

更新

我通过确保我的缓冲区包含数据来修复错误:

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);
    }
}

查看文件 $QTDIR/qtbase/src/corelib/tools/qarraydata.h,我们看到:

struct Q_CORE_EXPORT QArrayData
{
   [...]

   static const QArrayData shared_null[2];
   static QArrayData *sharedNull() Q_DECL_NOTHROW { return const_cast<QArrayData*>(shared_null); }
}

... 所以我们看到 QArrayData::shared_null 是一个 static/singleton QArrayData 对象(实际上它是其中两个的数组)。大概它被用作哨兵对象;即,当另一个数据结构(例如 Qt3DRender::QBuffer 没有指向有效的 QArrayData 对象时,它会指向 shared_null ,作为表明该事实的一种方式。使用单例而不是 nullptr 在某些情况下很有用,因为这意味着他们的代码不必使用 if (buffer() != NULL) 来保护每个取消引用以避免在没有有效的 QArrayData 对象可用时崩溃.

至于 +24 部分,这表明您的指针距离 QArrayData::shared_null 对象开始的内存位置 24 个字节。通过查看 qarraydata.h 中的代码,似乎 constData() 方法通过向其 this 指针添加 qptrdiff 偏移值来计算指向 return 的指针;所以大概在这种情况下偏移值设置为 24。但是,我认为精确的指针 returned 可能并不重要,因为 QArrayData::shared_null 对象在任何情况下都不太可能包含任何可用数据,即 data() 的数组是 returning 的长度可能为 0,因此不应取消引用指针。

我的建议是,在你尝试使用你的 posBufferPtr 指针之前,你应该调用 attribute->buffer()->data().size() 并验证它是否足够大以用于你想用它做的事情,作为完整性检查.也就是说,如果您尝试将缓冲区用作 float 的数组,请通过 if (attribute->buffer()->data().size() >= sizeof(float)*num_floats_I_expect_to_be_there) 或类似的测试来保护您对数据的使用。