违规写入动态分配数组的位置

问题描述 投票:0回答:1

我正在写一段代码。作为这段代码的一部分,我决定使用一个动态分配的数组来存储一组字符串。然而,当我尝试给数组赋值时,我得到了异常的结果

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

从研究这个主题看来,这个异常主要出现在你尝试向数组外写东西的时候。但是在我写的for循环里面,应该是不可能写到外面的。异常发生在

         posResponsesTeamNames[i] = teamName;   

而我的代码是

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;
}
c++ visual-c++ dynamic-arrays
1个回答
1
投票
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    }

假设价值: 联盟::numTeams 是10

在第2行,你创建了一个大小为10(league::numTeams)的数组。

在第7行,创建了一个局部变量counter i.

在第8行,创建一个局部变量 队名

在第9行,将0分配给 i(在第7行创建的),并开始了一个循环。 在这个循环中,你正在递增它。队名 可超过10(联盟::numTeams). 让我们假设12。

那么 i 可能大于10(league::numTeams)。现在在第12行,你将值赋于 posResponsesTeamNames 在位 i 也就是 12 现在。这个任务肯定会失败。

可能的解决方案在第9行,改用 i,使用 int j 作为局部变量的第二个计数器 队名

我希望这能给你答案。


0
投票

当你调用'new'关键字时,就是在调用你的类的构造函数。如果你的constrictor将你新分配的对象实例化为null,然后在你的循环中去引用那个对象,那就会产生访问违规。如果你的constrictor以一种允许立即去引用的方式初始化你的对象(初始化为空字符串""),这可能允许你向那个 "新 "对象写入而不会产生访问违规。

© www.soinside.com 2019 - 2024. All rights reserved.