Search code examples
c++visual-c++dynamic-arrays

Access violation writing location dynamically allocated array


I am writing a piece of code. As part of this code I have decided to use a dynamically allocated array to store a set of strings. However when i try and assign a value to my array i get the exception

Exception thrown at 0x50D540C9 (vcruntime140d.dll) in Glicko2.exe: 0xC0000005: Access violation writing location 0xC39903E3.

From researching this topic it seems that this exception mainly appears if you try and write to outside of your array. However inside the for loop where i am writing it, it should be impossible to write outside of it. The exception happens at the line

         posResponsesTeamNames[i] = teamName;   

and my code is

int league::matchSet()
{
    std::string currLine;
    std::string *posResponsesTeamNames = new std::string[league::numTeams];
    std::string posResponsesWon[3] = { "1","2","3" };
    team* team1;
    team* team2;
    bool successful = false;
    for (int i = 0; i < league::numTeams; i++) {
         std::string teamName = league::getName(i + 1);
         for (i = 0; i < teamName.size(); i++) {
             teamName.at(i) = toupper(teamName.at(i));
         }
         posResponsesTeamNames[i] = teamName;   
    }
    std::cout << posResponsesTeamNames[1];
roundStart:
    for (int i = 0; i < league::numMatches; i++) {
        std::cout << "for match " << i + 1 << " please enter name of first team to play: ";
        std::getline(std::cin, currLine);
        int parsed = parseText(currLine, posResponsesTeamNames);
        if (parsed == 2) {
            delete[] posResponsesTeamNames;
            prepForEnd();
            return 2;
        }
        else if (parsed == 0) {
            goto roundStart;
        }
        for (int i = 0; i < league::teams.size(); i++) {
            if (currLine == league::teams.at(i).getName()) {
                successful = true;
                team1 = &league::teams.at(i);
            }
        }
        if (successful == false) {
            std::cout << "ERROR: Invalid team name entered";
            goto roundStart;
        }
secondTeam:
        std::cout << "for match " << i + 1 << " please enter name of second team to play: ";
        std::getline(std::cin, currLine);
        parsed = parseText(currLine, posResponsesTeamNames);
        if (parsed == 2) {
            delete[] posResponsesTeamNames;
            prepForEnd();
            return 2;
        }
        else if (parsed == 0) {
            goto secondTeam;
        }
        for (int i = 0; i < league::teams.size(); i++) {
            if (currLine == league::teams.at(i).getName()) {
                successful = true;
                team2 = &league::teams.at(i);
            }
        }
        if (successful == false) {
            std::cout << "ERROR: Invalid team name entered";
            goto secondTeam;
        }
whoWon:
        std::cout << "please enter 1 if the first team won, 2 if the second team won or 3 if it was a draw: ";
        std::getline(std::cin, currLine);
        parsed = parseText(currLine, posResponsesWon);
        if (parsed == 2) {
            delete[] posResponsesTeamNames;
            prepForEnd();
            return 2;
        }
        if (parsed == 0) goto whoWon;
    }
    delete[] posResponsesTeamNames;
}

Solution

  • 1    std::string currLine;
    2    std::string *posResponsesTeamNames = new std::string[league::numTeams];
    3    std::string posResponsesWon[3] = { "1","2","3" };
    4    team* team1;
    5    team* team2;
    6    bool successful = false;
    7    for (int i = 0; i < league::numTeams; i++) {
    8         std::string teamName = league::getName(i + 1);
    9         for (i = 0; i < teamName.size(); i++) {
    10             teamName.at(i) = toupper(teamName.at(i));
    11        }
    12       posResponsesTeamNames[i] = teamName;   
    13    }
    

    Assumption: value of league::numTeams is 10

    at line no 2 you are creating an array of size 10(league::numTeams).

    at line 7, created a local variable counter i.

    at line 8, creating a local variable teamName

    at line 9, assigning 0 to i(created at line 7) and started a loop. you are incrementing it in this loop. size of teamName may be more than 10(league::numTeams). Lets assume 12.

    So the value of i may be more than 10(league::numTeams). Now at line 12, you are assigning value in posResponsesTeamNames at position i which is 12 now. This assignment will fail for sure.

    Possible Solution: at line 9, instead using i, use int j as a second counter on local variable teamName

    I hope this gives you answer.