0

Apparently, when my code reaches this if statement, a string subscript out of range exception occurs.

// a is int
// str is std::string

while ( true )
{    
// other stuff
if( a == str.size() ) // this line throws an exception
    break;
}

In what case can such a simple if-statement throw an exception? I just don't see it. Shouldn't it simply return 0 if for some reason the comparison fails?

EDIT: This is the full function in which it occurs. It basically reads through a file and takes in the value of some tokens of its. And if it is of some relevancy, I'm using Visual Studio 2010 Express and the error says "Debug Assertion Failed".

void Function(string &str, int start)
{
    int outline;

    // Read all attributes
    int pos, pos2 = start;
    while( true )
    {       
        pos = SkipWhiteSpace(str, pos2);
        pos2 = FindEndOfToken(str, pos);

        string token = str.substr(pos, pos2-pos);

        pos = SkipWhiteSpace(str, pos2);
        if( pos == str.size() || str[pos] != '=' ) break;

        pos = SkipWhiteSpace(str, pos+1);
        pos2 = FindEndOfToken(str, pos);
        file<<"...part 3";

        string value = str.substr(pos, pos2-pos);

        if( token == "outline" )
            outline = (short)strtol(value.c_str(), 0, 10);

        if( pos == str.size() ) // <--- error here (at least, it seems so)
            break;      
    }

    SetOutline(outline);
}

And the SkipWhiteSpace() and FindEndOfToken() functions are these two.

int SkipWhiteSpace(string &str, int start)
{
    UINT n = start;
    while( n < str.size() )
    {
        char ch = str[n];
        if( ch != ' ' && 
            ch != '\t' && 
            ch != '\r' && 
            ch != '\n' )
            break;

        ++n;
    }

    return n;
}

int FindEndOfToken(string &str, int start)
{
    UINT n = start;
    if( str[n] == '"' )
    {
        n++;
        while( n < str.size() )
        {
            char ch = str[n];
            if( ch == '"' )
            {
                // Include the last quote char in the token
                ++n;
                break;
            }
            ++n;
        }
    }
    else
    {
        while( n < str.size() )
        {
            char ch = str[n];
            if( ch == ' ' ||
                ch == '\t' ||
                ch == '\r' ||
                ch == '\n' ||
                ch == '=' )
                break;

            ++n;
        }
    }

    return n;
}
Banderi
  • 656
  • 3
  • 7
  • 29
  • An [SSCCE](http://sscce.org) would help. – chris Aug 23 '13 at 16:41
  • This line would throw an exception if the code ahead of it exhibited undefined behavior, and illegally modified the content of `str`'s internals. – Sergey Kalinichenko Aug 23 '13 at 16:46
  • 1
    If anything `// other stuff` (whatever it really is) is a suspect. – jrok Aug 23 '13 at 16:48
  • Stack overflow due to compare signed/unsigned (I assume a becomes negative) –  Aug 23 '13 at 16:50
  • Good point, I know GCC warns for signed/unsigned comparisons. – chris Aug 23 '13 at 16:51
  • @chris I thought this was a fair enough SSCCE; I can't see how to reproduce this otherwise, though. EDIT: I'm gonna add the full code if it helps; – Banderi Aug 23 '13 at 16:51
  • Is the string modified in "other stuff"? What's the value of "a"? You need to give us a bit more to work off here. – Eddy Luten Aug 23 '13 at 16:54
  • Well, now that the comparison issue was brought up, it could be, but there's nothing we can really test to recreate the problem and play around to fix it. – chris Aug 23 '13 at 16:54
  • I added the full function in which it occurs – Banderi Aug 23 '13 at 17:01
  • 1
    Are you 100% sure it says "string _submission_ out of range"? Isn't it rather "string _subscript_ out of range"? – gx_ Aug 23 '13 at 17:07
  • Err... it actually is _subscript_. I hope I din't facepalm'd too bad... – Banderi Aug 23 '13 at 17:09
  • Did you try clicking the `Retry` button in the "Debug Assertion Failed!" pop-up window then explore back the call stack in the debugger? – gx_ Aug 23 '13 at 17:15
  • It triggers a breakpoint and brings me over `if(::_CrtDbgReportW(_CRT_ASSERT, file, line, NULL, message)==1) { ::_CrtDbgBreak(); }`, but I don't know how to read the debug after that – Banderi Aug 23 '13 at 17:19
  • Sorry, we can't debug your (incomplete) code for you (yes, incomplete: where's the `main`?). You need to use your IDE with its debugger and Call Stack window ([this](http://loulou.developpez.com/tutoriels/cpp/debogueur-visual-studio/images/vectormain.png)). – gx_ Aug 23 '13 at 17:27
  • That's exactly why I asked in which case such an error could occur. I could never ask someone else to fully debug my code. – Banderi Aug 23 '13 at 17:29
  • 1
    @Banderi Dammit, use some unsigned type when comparing to container.size(). –  Aug 23 '13 at 17:31
  • ,,. that code is weird enough. –  Aug 23 '13 at 17:38
  • @DieterLücking I quickly tried to forcefully keep all the types to unsigned, it either didn't work or the problem is not that one. However I'm 99% sure that the exception/error/whatever occurs in that very line of code.. Anyway, I didn't write that code. I'm just using it, and the author said it never had such a problem before and it still works for him. – Banderi Aug 23 '13 at 17:41
  • @DieterLücking Well, thanks for the help anyways. – Banderi Aug 23 '13 at 17:53
  • @Banderi This is a really bad bet: Find a -1 passed to your functions. –  Aug 23 '13 at 17:58
  • 1
    Searched for a good hour, still nothing like that. Instead, I found that before reaching the end of the main token (the if-statement) there was another part it was parsing, and the actual error is in the `FindEndOfToken()` function. I'm gonna look inside it... I apologize for making you guys waste time after a ghost, though. – Banderi Aug 23 '13 at 20:16

1 Answers1

0

This line can never throw an exception. Are you sure what you get is a real C++ exception and not a crash?

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • Well, the visual error message says "exception" ans "string submission out of range", so I thought it was a simple exception.. The error is the "Debug Assertion Failed!" message and points to line 1441 of file "xstring", saying that it is an exception. After that, it crashes. – Banderi Aug 23 '13 at 16:49
  • Theoretically, it could throw some kind of integer overflow/out of range exception, if the coercion of `a` (assuming it is really an `int` aka `std::int32_t`) and `std::size_t` did not work and if the underlying run-time supports and observes that... Hm, a bit of too many "ifs" – Paul Michalik Aug 23 '13 at 16:49
  • Pardon. It's _subscript_, not _submission_. – Banderi Aug 23 '13 at 17:11
  • This line could throw an exception if there was undefined behavior in the program. You can never say never in C++, because of undefined behavior. – James Kanze Aug 23 '13 at 17:42
  • And of course, "Debug Assertion Failed" is not what we would usually consider an exception. It generally means that his instance of the string is corrupt somehow. – James Kanze Aug 23 '13 at 17:43
  • My bad again, it appears it is not that one line that causes the error. I'm gonna look for it, but I think this question can be considered closed. – Banderi Aug 23 '13 at 20:23