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. [SOLVED] QString.at(), debug, VC++ Rt error if string empty (Qt 5.5.0)
Forum Updated to NodeBB v4.3 + New Features

[SOLVED] QString.at(), debug, VC++ Rt error if string empty (Qt 5.5.0)

Scheduled Pinned Locked Moved General and Desktop
7 Posts 4 Posters 3.4k Views 2 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.
  • T3STYT Offline
    T3STYT Offline
    T3STY
    wrote on last edited by T3STY
    #1

    I was running some code that used a QString array and the method at() on an item. It compiled just fine but, as soon as the application started, it thrown a Visual C++ Runtime error. The error only happens in debug mode. The code I'm running is in a class, the important part is this:

    class something{
    enum errorLevel{
        EL_NONE=0,
        EL_INFO,
        EL_WARNING,
        EL_ERROR
    };
    
    // ....
    void print(QString message, errorLevel EL){
        QString tmpMsg;
        // some other code...
    	QString el_msg[4] = {"", "info", "warning", "error"};
        tmpMsg.replace("%e" ,  el_msg[EL].at(0));
    }
    };
    

    Sometimes the VC++ error message would also report an issue at line 851 in file qstring.h. Next there is the code at line 850-851 in that file:

    inline const QChar QString::at(int i) const
    { Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
    

    The problem seems to be that the assertion fails, as reported by Qt Creator's Application output panel:

    ASSERT: "uint(i) < uint(size())" in file D:/DevTools/qt-builds/qt-5.5.0-x64-mingw510r0-sjlj/include/QtCore/qstring.h, line 851
    

    The error only happens with an empty ( "" ) string. Anything else seems to be ok.
    I would report that to the developers but it might also be an issue in the VC++ RT library. Does this error happen to anyone? Or maybe it has been fixed already in a newer Qt release?

    1 Reply Last reply
    0
    • MrBoltonM Offline
      MrBoltonM Offline
      MrBolton
      wrote on last edited by
      #2

      Hi,

      as I see it, it should only crash when you pass in EL_NONE as the errorLevel parameter.
      In this line tmpMsg.replace("%e" , el_msg[EL].at(0)); you grab the QString at position 0 (since EL_NONE=0) from the QString array.
      The QString you get is empty, but still you try to get the character at position 0 (with at(0)) and this is where the program crashes, since there is nothing at this position.

      Btw this is what the ASSERT is trying to tell you. The parameter i which you pass into at(int i) is bigger than the size of the QString object.

      Hope this helps!
      Tobi

      1 Reply Last reply
      0
      • T3STYT Offline
        T3STYT Offline
        T3STY
        wrote on last edited by T3STY
        #3

        Yes, I understand that getting a character from an empty string fails. However, this behaviour is wrong.
        Getting a character from an empty string should return an empty string, not fail. At most, a warning or an error should be raised in debug mode, but not in any case should that small error crash the application like it happens now.
        If we accepted this wrong behaviour then QString::chop() should fail as well on an empty string, as well as most of the other methods available in the QString class (such as remove, replace, left, right and so on).

        BTW I worked around the problem by using a space instead of an empty string

        1 Reply Last reply
        0
        • jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          "However, this behaviour is wrong." - no, it isn't.
          Please check the QString documentation:
          const QChar QString::at(int position) const
          Returns the character at the given index position in the string.
          The position must be a valid index position in the string (i.e., 0 <= position < size()).

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

          1 Reply Last reply
          1
          • JKSHJ Offline
            JKSHJ Offline
            JKSH
            Moderators
            wrote on last edited by JKSH
            #5

            @T3STY said:

            Getting a character from an empty string should return an empty string, not fail.

            No, @jsulm is correct.

            In essence, a string is an array of characters. In C++, if you try to retrieve an array element that is beyond the array's range, your program will crash:

            int intArray[] = {1, 2, 3, 4, 5};
            int i = intArray[7]; // Crash!
            
            QString str1("Hello");
            str1[0]; // OK, returns 'H'
            str1[7]; // Crash!
            str1.at(7); // Crash!
            
            QString str2;
            str2[0]; // Crash!
            str2.at(0); // Crash!
            

            Accessing items outside of an array's range is forbidden in C++: http://www.cplusplus.com/reference/stdexcept/out_of_range/

            If we accepted this wrong behaviour then QString::chop() should fail as well on an empty string

            That function is designed to perform checks to make sure that the range is valid.

            However, if we did that for QString, std::vector, or others, the performance of some applications will grind to a halt. So, it's the programmer's responsibility to ensure that you don't access items out of an array's range.

            Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

            1 Reply Last reply
            1
            • T3STYT Offline
              T3STYT Offline
              T3STY
              wrote on last edited by T3STY
              #6

              OK, I'll keep my workaround space until I'll find some other solution.
              However I still think you should not crash the program upon such thing. After all, QString is a class built specifically to make it easier to work on strings, which implies to avoid out of bounds crashes, full of rarely used methods and full of other checks to make sure everything is fine. I think a simple check if (size() <= 0) return ""; will not impact that much on performance...

              p.s. If you don't make that check in the QString class, it means the user has to make it. Either way, there is a check to make and a performance loss anyway.

              JKSHJ 1 Reply Last reply
              0
              • T3STYT T3STY

                OK, I'll keep my workaround space until I'll find some other solution.
                However I still think you should not crash the program upon such thing. After all, QString is a class built specifically to make it easier to work on strings, which implies to avoid out of bounds crashes, full of rarely used methods and full of other checks to make sure everything is fine. I think a simple check if (size() <= 0) return ""; will not impact that much on performance...

                p.s. If you don't make that check in the QString class, it means the user has to make it. Either way, there is a check to make and a performance loss anyway.

                JKSHJ Offline
                JKSHJ Offline
                JKSH
                Moderators
                wrote on last edited by
                #7

                @T3STY said:

                I still think you should not crash the program upon such thing. After all, QString is a class built specifically to make it easier to work on strings, which implies to avoid out of bounds crashes, full of rarely used methods and full of other checks to make sure everything is fine.

                If you believe that Qt should change its design, I recommend you subscribe to the Development mailing list and post there. Qt's engineers are active on that list; you can present your suggestion to them directly.

                I think a simple check if (size() <= 0) return ""; will not impact that much on performance...

                See http://stackoverflow.com/questions/24312601/is-bounds-checking-in-c-or-c-expensive

                p.s. If you don't make that check in the QString class, it means the user has to make it. Either way, there is a check to make and a performance loss anyway.

                There's a big difference between checking only when required versus checking every single character in the string.

                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                1 Reply Last reply
                0

                • Login

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