Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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.


  • Qt Champions 2019

    @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 do

    for(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.


  • Moderators

    @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 in listK, the original items in mapK will still remain the same (unless you use pointers).



  • 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?


  • Moderators

    @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
    
    

Log in to reply