如何在Qt容器中获得原始数据的指针

How to get pointer to raw data in Qt containers?

本文关键字:原始数据 指针 Qt      更新时间:2023-10-16

这展示了如何访问std::vector中指向原始数据的指针。我想要类似的东西,在Qt的QVector, QQueue和QList(如果可能的话,其他容器)。

例如我们有一些容器:

QVector<int> vector;
QQueue<int> queue;
QList<int> list;

和这些指针:

int * p1 = &vector[0];
int * p2 = &queue[0];
int * p3 = &list[0];

上面的指针指向容器中的原始数据吗?

对于上面的例子,我做了一个测试。代码是:
QVector<int> vector;
QQueue<int> queue;
QList<int> list;
for(int i=0;i<10;i++)
{
    vector.append(i);
    queue.enqueue(i);
    list.append(i);
}
int * P1 = &vector[0];
int * P2 = &queue[0];
int * P3 = &list[0];
for(int i=0;i<10;i++)
    qDebug()<<P1[i]<<P2[i]<<P3[i]<<"n";

结果是:

0 0 0

1 1 1

2

3

4 4 4

5

6 6 6

7 7 7

8 8 8

9

所以至少对于int类型是成立的

但是相同的双类型测试失败了。对于double类型,只有QVector元素是正确的。

是否可以在QQueue和QList中获得原始数据的指针?

这似乎不是一个好主意,并且可能在将来的某个随机点出现分段错误而失败。QList和QQueue没有data()函数的原因是QList不保证列表项在内存中彼此相邻。比较:

QVector是Qt的一个泛型容器类。它将项存储在相邻的内存位置,并提供快速的基于索引的访问。

List是Qt的一个泛型容器类。存储值列表,并提供快速的基于索引的访问以及快速的插入和删除。

您的测试表明它现在可以工作,并且它似乎也可以处理10000或1000000个项目。但这是一个实现细节,不能保证未来的Qt版本不会因为性能或其他原因而改变QList的内部工作。

还有一个问题:任何比指针大的(例如QList<someStruct>)都只会作为指针存储在列表中,而实际的项则驻留在堆中。


事实上,Qt文档指出QList在内部使用数组:

在内部,QList使用数组实现,确保基于索引的访问非常快。

但这并不一定意味着所有项都是连续的。您可能会想象一个牵强的实现,其中列表存储项块,这样每个块都是一个单独的数组。

可以使用Qt函数正确地完成。例如:

QVector<int> vector;
int* ptr = vector.data();