Unsolved QMAP is suddenly Empty! Bug or I'm I using it wrong?
-
Hi all,
I've a map of 'courses' called mapK. Each 'course' (class D_Kurs) has its own (mapSchiene). Due to debugging I made 'mapSchiene' public. So here is my code and the weird result.
QList<D_Kurs> listK = mapK.values(); foreach(D_Kurs dk, listK) { dk.mapSchiene["la"] = 7; qDebug() << dk.getName() << " --A--> " << dk.mapSchiene.size(); } foreach(D_Kurs dk, listK) { qDebug() << dk.getName() << " --B--> " << dk.mapSchiene.size(); }
I don't understand, why the individual QMaps are empty in the second iteration.
"PJ-BI-PJK1" --A--> 1 "D-LK1" --A--> 1 "D-LK2" --A--> 1 ... "PJ-BI-PJK1" --B--> 0 "D-LK1" --B--> 0 "D-LK2" --B--> 0
Could you please help me. Thx.
-
@Benjamin-B. said in QMAP is suddenly Empty! Bug or I'm I using it wrong?:
foreach(D_Kurs dk, listK) { dk.mapSchiene["la"] = 7;
You're adding calues to a local object here.
You may want to dofor(D_Kurs &dk : listK) { dk.mapSchiene["la"] = 7; } or for(auto it = listK.begin(); it != listK.end(); ++it) { D_Kurs &dk = it.value(); dk.mapSchiene["la"] = 7; }
foreach won't work here at all because it's creating a copy of the container internally iirc.
-
@Benjamin-B. said in QMAP is suddenly Empty! Bug or I'm I using it wrong?:
foreach(D_Kurs dk, listK) {
Here foreach is making a copy of each element from listK. So when you modify that copy in
dk.mapSchiene["la"] = 7;
it is destroyed when it goes out of scope (the closing bracket}
).Then when you read your
listK
again, you read (again) the original list - without the changes you've made.In order to modify the map in-place, you can do 2 things:
- use pointers in mapK / listK. Just remember you are responsible for object lifetime (need to call
delete
when objects are not needed anymore) - replace the objects after you modify them. So, you take a value from your map / list, modify it, then call insert() or replace() on your ma to overwrite the original value
Another thing to remember: when you call
mapK.values()
you are also making a copy of the values. So if you replace the items inlistK
, the original items inmapK
will still remain the same (unless you use pointers). - use pointers in mapK / listK. Just remember you are responsible for object lifetime (need to call
-
Thank you for your comments...its really hard for me to handle pointers, since I am used to JAVA.
I wanted to store in mapK pointers so I did.
QMap<int, D_Kurs*> mapK;
adding to it like:
int kID = 0; foreach (QString line, listK) { D_Kurs dk(kID, line); mapK.insert(kID, &dk); kID++; }
and accessing it:
for(D_Kurs *dk : mapK.values()) { dk->mapSchiene["la"] = 7; // HERE ERROR qDebug() << dk->getName() << " --A--> " << dk->mapSchiene.size(); } for(D_Kurs *dk : mapK.values()) { qDebug() << dk->getName() << " --B--> " << dk->mapSchiene.size(); }
But I get an error. Could you help?
-
@Benjamin-B. said in QMAP is suddenly Empty! Bug or I'm I using it wrong?:
foreach (QString line, listK) {
D_Kurs dk(kID, line);
mapK.insert(kID, &dk);
kID++;
}You create
dk
on stack, so it gets automatically destroyed when scope ends (}
). Create a pointer instead:auto dk = new D_Kurs(kID, line); mapK.insert(kID, dk); [...]
And btw. if you are only storing indexes in keys, then you may want to use QVector or QList instead of QMap. QMap/QHash make more sense when the keys are something different (strings, non-continuous integers, negative nhumbers etc.).
-
...ahhhhh (Stack!) I'm starting to understand (starting to remember: some time ago i studied computer science)!
"And btw. if you are only storing indexes in keys, then you may want to use QVector or QList instead of QMap. QMap/QHash make more sense when the keys are something different (strings, non-continuous integers, negative nhumbers etc.)."
...yes i know, the keys may later be arbitrary (when keys get deleted).
Thank you a lot!!!
-
Don't forget to delete the dynamically allocated itens.
// Deleting the itens qDeleteAll(mapK); // remove the itens from memory mapK.clear(); // remove the pointers to itens from map