访问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)
或类似的测试来保护您对数据的使用。
我有这样的说法:
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)
或类似的测试来保护您对数据的使用。