Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QMap iteration gets inexisting item
Qt 6.11 is out! See what's new in the release blog

QMap iteration gets inexisting item

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 4 Posters 537 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Andrew23
    wrote on last edited by aha_1980
    #1

    When I iterate a QMap for the second time I get an inexisting item why?

    typedef struct
    {
        uint8_t connected;
        QByteArray address;
        uint8_t type;
        uint8_t enabled;
    
    } item_t;
    
    QMap<uint8_t, item_t> map;
    
    void Foo( QByteArray address, uint8_t connectionState, uint8_t itemType, uint8_t id )
    {
        if ( map.contains( id ) == false )
        {
            map.insert( id, { .connected = connectionState, .address = address, .type = itemType, .enabled = 0 } );
        }
        else
        {
            map[ id ].connected = connectionState;
        }
    
        foreach ( const uint8_t &key, map.keys() )
        {
            qDebug() << "id" << key << "-" << map[ key ].address.toHex( ':' ) << "- connectionState" << map[ key ].connected;
        }
    }
    

    If i run Foo( hereByteArray, 1, 1, 1 ) the output is

    id 1 - "28:9e:39:68:72:e8" - connectionState 1
    

    as expected. But If I continue to run Foo( hereByteArray, 0/1, 1, 1 ) the output become

    id 0 - "" - connectionState 0
    id 1 - "28:9e:39:68:72:e8" - connectionState 0
    

    even if I never insert the item "0". Why ?

    Pl45m4P jsulmJ 2 Replies Last reply
    0
    • A Andrew23

      When I iterate a QMap for the second time I get an inexisting item why?

      typedef struct
      {
          uint8_t connected;
          QByteArray address;
          uint8_t type;
          uint8_t enabled;
      
      } item_t;
      
      QMap<uint8_t, item_t> map;
      
      void Foo( QByteArray address, uint8_t connectionState, uint8_t itemType, uint8_t id )
      {
          if ( map.contains( id ) == false )
          {
              map.insert( id, { .connected = connectionState, .address = address, .type = itemType, .enabled = 0 } );
          }
          else
          {
              map[ id ].connected = connectionState;
          }
      
          foreach ( const uint8_t &key, map.keys() )
          {
              qDebug() << "id" << key << "-" << map[ key ].address.toHex( ':' ) << "- connectionState" << map[ key ].connected;
          }
      }
      

      If i run Foo( hereByteArray, 1, 1, 1 ) the output is

      id 1 - "28:9e:39:68:72:e8" - connectionState 1
      

      as expected. But If I continue to run Foo( hereByteArray, 0/1, 1, 1 ) the output become

      id 0 - "" - connectionState 0
      id 1 - "28:9e:39:68:72:e8" - connectionState 0
      

      even if I never insert the item "0". Why ?

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by Pl45m4
      #2

      @Andrew23 said in QMap iteration gets inexitent item:

      But If I continue to run Foo( hereByteArray, 0/1, 1, 1 ) the output become
      id 0 - "" - connectionState 0
      id 1 - "28:9e:39:68:72:e8" - connectionState 0

      even if I never insert the item "0". Why ?

      At first glance, I would say you fell for the []-operator "mistake".
      Try to avoid [] everywhere when dealing with QMaps.

      Because if you try to look-up a key-value pair with [] and the key is not found, it will construct an empty, default key value pair at this position.

      I could be wrong but this is what your [0] entry seems to be.
      Replace every access to the map with .value(key) and it should not happen anymore

      So instead of

      map[ key ].address.toHex( ':' )
      

      better (and everywhere else)

      map.value(key).address.toHex( ':' )
      

      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      A 1 Reply Last reply
      5
      • A Andrew23

        When I iterate a QMap for the second time I get an inexisting item why?

        typedef struct
        {
            uint8_t connected;
            QByteArray address;
            uint8_t type;
            uint8_t enabled;
        
        } item_t;
        
        QMap<uint8_t, item_t> map;
        
        void Foo( QByteArray address, uint8_t connectionState, uint8_t itemType, uint8_t id )
        {
            if ( map.contains( id ) == false )
            {
                map.insert( id, { .connected = connectionState, .address = address, .type = itemType, .enabled = 0 } );
            }
            else
            {
                map[ id ].connected = connectionState;
            }
        
            foreach ( const uint8_t &key, map.keys() )
            {
                qDebug() << "id" << key << "-" << map[ key ].address.toHex( ':' ) << "- connectionState" << map[ key ].connected;
            }
        }
        

        If i run Foo( hereByteArray, 1, 1, 1 ) the output is

        id 1 - "28:9e:39:68:72:e8" - connectionState 1
        

        as expected. But If I continue to run Foo( hereByteArray, 0/1, 1, 1 ) the output become

        id 0 - "" - connectionState 0
        id 1 - "28:9e:39:68:72:e8" - connectionState 0
        

        even if I never insert the item "0". Why ?

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @Andrew23 To add to @Pl45m4 this behavior is explained in the documentation which you should read: https://doc.qt.io/qt-6/qmap.html#operator-5b-5d

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        0
        • Pl45m4P Pl45m4

          @Andrew23 said in QMap iteration gets inexitent item:

          But If I continue to run Foo( hereByteArray, 0/1, 1, 1 ) the output become
          id 0 - "" - connectionState 0
          id 1 - "28:9e:39:68:72:e8" - connectionState 0

          even if I never insert the item "0". Why ?

          At first glance, I would say you fell for the []-operator "mistake".
          Try to avoid [] everywhere when dealing with QMaps.

          Because if you try to look-up a key-value pair with [] and the key is not found, it will construct an empty, default key value pair at this position.

          I could be wrong but this is what your [0] entry seems to be.
          Replace every access to the map with .value(key) and it should not happen anymore

          So instead of

          map[ key ].address.toHex( ':' )
          

          better (and everywhere else)

          map.value(key).address.toHex( ':' )
          
          A Offline
          A Offline
          Andrew23
          wrote on last edited by
          #4

          @Pl45m4 thanks a lot. Now it works without output the '0' item. Can you tell me if on the other side it's ok to use the [] operator to write the map item value?

          @jsulm thanks. I didn't see it.

          JonBJ 1 Reply Last reply
          0
          • A Andrew23

            @Pl45m4 thanks a lot. Now it works without output the '0' item. Can you tell me if on the other side it's ok to use the [] operator to write the map item value?

            @jsulm thanks. I didn't see it.

            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by
            #5

            @Andrew23 said in QMap iteration gets inexisting item:

            it's ok to use the [] operator to write the map item value?

            Yes, of course, since here you are writing to and/or creating the element, you don't have to worry about it auto-creating a "blank" one. What you should not do is read from map[...], e.g. if (map[...]) ... or qDebug() << map[...] since those would create the entry if it does not exist.

            A 1 Reply Last reply
            2
            • JonBJ JonB

              @Andrew23 said in QMap iteration gets inexisting item:

              it's ok to use the [] operator to write the map item value?

              Yes, of course, since here you are writing to and/or creating the element, you don't have to worry about it auto-creating a "blank" one. What you should not do is read from map[...], e.g. if (map[...]) ... or qDebug() << map[...] since those would create the entry if it does not exist.

              A Offline
              A Offline
              Andrew23
              wrote on last edited by
              #6

              Ok. Thanks!

              1 Reply Last reply
              0
              • A Andrew23 has marked this topic as solved on

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved