2

This shows how to access the pointer to the raw data in std::vector. I want something like that in Qt for QVector, QQueue and QList (If possible other containers).

For instance if we have some containers:

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

And these pointers:

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

Do the above pointers point to raw data in containers?

For the above case i made a test. The code is:

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";

And the result is:

0 0 0

1 1 1

2 2 2

3 3 3

4 4 4

5 5 5

6 6 6

7 7 7

8 8 8

9 9 9

So at least it is true for the case of int type.

But the same test with double type failed. Just QVector elements were correct for type double.

Is it possible to get pointer to raw data in QQueue and QList?

Community
  • 1
  • 1
Nejat
  • 31,784
  • 12
  • 106
  • 138
  • What if containers are empty? – vahancho Mar 18 '14 at 07:28
  • @ vahancho Assume that the containers are not empty. – Nejat Mar 18 '14 at 07:31
  • Well, but what you want is just a pointer to the first element of the container, and it makes sence only for arrays (vectors) to refer to them in such way. QList and QQueue are linked lists. – vahancho Mar 18 '14 at 07:32
  • 1
    I think it depends on how these containers are implemented. If they put data contiguously then i think the mentioned method would be right. – Nejat Mar 18 '14 at 07:37
  • No, they don't. Because data in queue does not stored as a raw sequence. You should learn http://en.wikipedia.org/wiki/List_of_data_structures – Dmitry Sazonov Mar 18 '14 at 08:37
  • This seems like a bad idea. You are relying on implementation details of the containers. As already stated, they offer no guarantee of supporting pointer arithmetic on pointers to individual elements. I would try and find a different approach to achieve what you're trying to do. – Erik J Mar 19 '14 at 12:38

2 Answers2

2

This does not seem like a good idea and might fail with a segmentation fault at some random point in the future. The reason that QList and QQueue don't have a data() function is that QList does not guarantee that the list items are next to each other in memory. Compare:

QVector is one of Qt's generic container classes. It stores its items in adjacent memory locations and provides fast index-based access.

vs.

List is one of Qt's generic container classes. It stores a list of values and provides fast index-based access as well as fast insertions and removals.

Your test indicates that it works right now, and it also seems to work with 10000 or 1000000 items. But that's an implementation detail and there's no guarantee that some future version of Qt won't change the internal workings of QList for performance or other reasons.

Also, there's a catch: Everything larger than a pointer (e.g. QList<someStruct>) will only be stored in the list as a pointer, while the actual item resides on the heap.


In fact, the Qt documentation states that QList does use arrays internally:

Internally, the QList is implemented using an array, ensuring that index-based access is very fast.

But even that wouldn't necessarily mean that all items are contiguous. One might imagine a far-fetched implementation where the list stores blocks of items, such that each block is an individual array.

Fritz
  • 1,293
  • 15
  • 27
1

It could be done properly using the Qt functions. For example:

QVector<int> vector;
int* ptr = vector.data();
hrkz
  • 378
  • 3
  • 14