QValueVector in Qt 3(.3.8) is broken
I have put a lot of effort to rewrite huge part of my app to work with QValueVector but all in vain. Below I present proof of this broken component. Correct me if I'm wrong and I'll be happy.
My code:
Code:
qDebug(">");
playlistsList::iterator i, j;
i = playlists.begin();
j = i;
i += where;
//qDebug(playlists.at(which).name);
//qDebug((*i).name);
for (int i = 0 ; i != playlists.count() ; i++, j++)
{
qDebug(playlists.at(i).name + " " + (*j).name);
}
qDebug("i'll insert " + playlists.at(which).name + " before " + (*i).name);
playlists.insert(i, playlists.at(which));
for (int i = 0 ; i != playlists.count() ; i++)
qDebug(playlists.at(i).name);
qDebug("after redundant removed");
i = playlists.begin();
j = i;
i += (which + 1);
playlists.erase(i);
for (int i = 0 ; i != playlists.count() ; i++, j++)
qDebug(playlists.at(i).name + " " + (*j).name);
qDebug("");
qDebug("");
Results after first execution of above code are correct:
Code:
>
aa aa
bb bb
i'll insert bb before aa
bb
aa
bb
after redundant removed
bb bb
aa aa
Second execution gives INCORRECT result:
Code:
>
bb bb
aa aa
i'll insert aa before bb
bb
bb
aa
after redundant removed
bb bb
bb bb
Can anyone help me?
Re: QValueVector in Qt 3(.3.8) is broken
Could you post a minimal compilable example?
Re: QValueVector in Qt 3(.3.8) is broken
Code:
/**
Broken QValueVector demo (Qt 3.3.8, GCC 4.1.1)
@author amdfanatyk
compilation: c++ qvalvecshit.cpp -o valvec -lqt-mt
**/
#include <qstring.h>
#include <qvaluevector.h>
struct elem
{
elem() {}
elem
(const QString & _s1,
const QString & _s2
) { s1
= _s1; s2
= _s2;
}
};
typedef QValueVector<elem> elemsList;
void printList(const elemsList & list)
{
qDebug("---");
for (int i = 0 ; i != list.count() ; i++)
qDebug(list[i].s1 + " " + list[i].s2);
qDebug("---");
}
void insertElem(elemsList & e)
{
if (e.count() < 2)
return;
elemsList::iterator i = e.begin();
printList(e);
qDebug("*- i'll insert " + e1s1 + " before " + e0s1);
e.insert(i, e.at(1));
printList(e);
if ((e.at(0).s1 != e1s1) || (e.at(1).s1 != e0s1))
qDebug("Ooops!");
else
qDebug("OK");
}
int main()
{
elemsList elems;
elem e1("a", "aa");
elem e2("b", "bb");
elems.append(e1);
elems.append(e2);
insertElem(elems);
insertElem(elems);
return 0;
}
Code:
---
a aa
b bb
---
*- i'll insert b before a
---
b bb
a aa
b bb
---
OK
---
b bb
a aa
b bb
---
*- i'll insert a before b
---
b bb
b bb
a aa
b bb
---
Ooops!
Re: QValueVector in Qt 3(.3.8) is broken
I've changed
Code:
e.insert(i, e.at(1));
to
Code:
elem el = e.at(1);
e.insert(i, el);
and it seems to work OK now.
IMO the problem is that at() returns a reference, which is valid only while the vector remains unchanged. But insert() has to make space for the new item, so it moves existing items and the reference becomes invalid.
Re: QValueVector in Qt 3(.3.8) is broken
Thanks. Now it works but I don't think I'll use QValueVector and QTL. For me that's a bug. insert() should insert a copy of, so first it should make a copy and then insert it. To get it work I must make one copy and then vector makes another copy and I waste a lot of memory, it sucks. When I use my own engine I only change values of pointers - there is no need to make copies and remove redundant objects. With QPtrVector I think I'll have similar problems.
Re: QValueVector in Qt 3(.3.8) is broken
Quote:
Originally Posted by
fear
For me that's a bug. insert() should insert a copy of, so first it should make a copy and then insert it.
insert() itself is OK. The problem is that the item is passed by reference.
Quote:
Originally Posted by
fear
When I use my own engine I only change values of pointers - there is no need to make copies and remove redundant objects.
That's how QPtrVector works. QValueVector, just like std::vector, stores items, not pointers, so it has to copy them. But if you have your own collection that suits you better, just use it.