1

I'm working off of a tutorial to learn C++ using the most recent version of Visual Studio Community 2017 on an updated version of Windows 8.1.

When I adjusted the following .cpp file and ran the program it crashed after entering an input with the error:

Debug Assertion Failed!

Program C:\WINDOWS\SYSTEM32\MSVCP140D.dll File c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.11.25503\include\xstring Line: 2969

Expression string subscript out of range

#include "stdafx.h"
#include "FBullCowGame.h"

using int32 = int;

FBullCowGame::FBullCowGame() { Reset(); }

int32 FBullCowGame::GetMaxTries() const { return MyMaxTries; }
int32 FBullCowGame::GetCurrentTry() const { return MyCurrentTry; }

void FBullCowGame::Reset()
{
    constexpr int32 MAX_TRIES = 8;
    MyMaxTries = MAX_TRIES;

    const FString HIDDEN_WORD = "ant";
    MyHiddenWord = HIDDEN_WORD;

    MyCurrentTry = 1;
    return;
}


bool FBullCowGame::IsGameWon () const { return false; }

bool FBullCowGame::CheckGuessValidity(FString)
{
    return false;
}
// Receives a VALID guess, increments turn, and returns count

FBullCowCount FBullCowGame::SubmitGuess(FString Guess)
{
    // incriment the turn number
    MyCurrentTry++;

    // setup a return variable
    FBullCowCount BullCowCount;

    // loop through all letters in the guess
    int32 HiddenWordLength = MyHiddenWord.length();
    for (int32 i = 0; i < Guess.length(); i++) {
        // compare letters against the hidden word
        for (int32 j = 0; j < HiddenWordLength; j++) {
            // if they match then
            if (Guess[j] == MyHiddenWord[i]) {
                if (i == j) { // if they're in the same place
                    BullCowCount.Bulls++; // incriment bulls
                }
                else {
                    BullCowCount.Cows++; // must be a cow
                }
            }
        }
    }
    return BullCowCount;
}

When debugging it took me to the line referred to in xstring it gives the following error:

Unhandled exception at 0x1005E5F6 (ucrtbased.dll) in BullCowGame.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

for the code:

    reference operator[](const size_type _Off)
    {   // subscript mutable sequence
    auto& _My_data = this->_Get_data();
    _IDL_VERIFY(_Off <= _My_data._Mysize, "string subscript out of range");
    return (_My_data._Myptr()[_Off]);
    }

There appears to be a breakpoints triggered by something I did, but the code reflects the code in the tutorial and the tutorial code compiles and runs correctly.

Does anyone know how to deal with this? I'm coming up empty on searches.

Community
  • 1
  • 1
James
  • 13
  • 1
  • 4
  • 3
    Have you stepped through your code using a debugger while it was executing? Likely this line is indexing out of range `Guess[i] == MyHiddenWord[i]` – Cory Kramer Sep 06 '17 at 18:22
  • 2
    Your loops don't seem to be taking into account the length of the Guess string. Are you sure that Guess has the same length (or greater) than the hidden word? – drescherjm Sep 06 '17 at 18:29
  • Hi CoryKramer - After stop-debugging it appears to throw the error on what is probably the last iteration of that for loop when MyHiddenWord == 3. It jumps to the line in xstring referenced above the first few iterations of the loop without a problem, but on that last iteration it appears to be triggering the breakpoint in xstring. – James Sep 06 '17 at 18:48
  • Hi drescherjm, no I do not, and according to the tutorial I am following it doesn't seem to be necessary for the code to run. May I ask what you're thinking the problem may be? As I stated above to Cory the breakpoint IS triggering in the last iteration of the loop, so maybe you're onto something. It seems to work for the person giving the tutorial. – James Sep 06 '17 at 18:50
  • Online tutorials are often wrong. I highly recommend against them as a primary source of learning. – drescherjm Sep 06 '17 at 19:43
  • So manuals, then? – James Sep 06 '17 at 19:51
  • I recommend learning from a book first. https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – drescherjm Sep 06 '17 at 21:17
  • I would start by replacing `for (int32 i = 0; i < HiddenWordLength; i++)` with `for (int32 i = 0; i < Guess.length(); i++)` – drescherjm Sep 06 '17 at 21:24
  • I believe `BullCowCount.Cows++;` will be incorrectly incremented if the hidden word has a letter used more than 1 time. – drescherjm Sep 06 '17 at 21:26
  • I changed the answer to reflect your suggested change, however I'm still receiving the error. Thanks for the book suggestion. I was planning on working on the cow incrementing after solving this issue, but yes I did see that they may increment incorrectly. I'm just vested in solving this crash first. – James Sep 06 '17 at 21:47
  • I picked the wrong loop to change sorry. The following should fix that: Change `Guess[j] == MyHiddenWord[i]` to `Guess[i] == MyHiddenWord[j]` – drescherjm Sep 06 '17 at 21:48
  • Brilliant! Thank you for your persistence! Please post it as an answer and I will check it as the solution! – James Sep 06 '17 at 21:53
  • I don't mind if you give Chris the credit for that. Next time you probably should not edit the code from the comments or if you do leave the original code in the question. – drescherjm Sep 06 '17 at 22:05
  • K. Done. Thanks again! And sharp thinking! – James Sep 06 '17 at 22:06

1 Answers1

0

This looks very suspicious:

for (int32 i = 0; i < Guess.length(); i++) {
    // compare letters against the hidden word
    for (int32 j = 0; j < HiddenWordLength; j++) {
        ...

Notice, i is bounded by guess's length, and j is bounded by HiddenWord's length.

Note you mixed up your index variables here:

        // if they match then
        if (Guess[j] == MyHiddenWord[i]) {

Also, you should have been looking at this line anyway, since the exception was in operator[], and this is the only place in the code you posted that uses the operator in question... :)

Chris Uzdavinis
  • 6,022
  • 9
  • 16