超出范围错误

时间:2014-10-10 18:15:52

标签: c++ vector range

问题是:

周杰伦借了一个朋友的咖啡杯,不知何故失去了它。由于他的朋友在发现这件事时会非常生气,杰伊决定给他的朋友买一个替换杯来试图控制伤害。 不幸的是,杰伊不记得他借来的那个杯子的颜色。他只知道颜色是白色,黑色,蓝色,红色或黄色。 杰伊绕着他的办公室问他的同事他们是否能够回忆起颜色,但他的朋友似乎也不记得那个杯子的颜色。他们所知道的是杯子绝对不是什么颜色。 根据这些信息,帮助杰伊弄清楚这个杯子的颜色是什么。

我正在采取的方式:

我创建了一个所有可能颜色的矢量:白色,黑色,蓝色,红色或黄色。然后要求用户输入他将要提问的同事人数。然后获取颜色建议,并为每个条目将其与向量进行比较。如果它在那里,我会把颜色弹出来。最终只有一种颜色留在矢量中,这是丢失的杯子的颜色。

我的问题:

输入第一种颜色后出现错误,我无法找出原因。确切的错误是:

terminate called after throwing an instance of 'std::out_of_range'
what():  vector::_M_range_check
Abort (core dumped)

我的代码是:

        #include <iostream>
        #include <string>
        #include <algorithm>
        #include <climits>
        #include <stdio.h>
        #include <vector>

        using namespace std;

        int main(int argv, char* argc[])
        {
            string color;
            vector<string> colorVector;

            colorVector.push_back("White");
            colorVector.push_back("Black");
            colorVector.push_back("Blue");
            colorVector.push_back("Red");
            colorVector.push_back("Yellow");

            int numColleagues;

            cout<< "Please enter the number of Colleagues" << endl;
            cin >> numColleagues;

            cout<< "Please enter each suggested color" << endl;

            int counter = 0;
            while (counter < numColleagues) {
            getline(cin, color);
            counter++;

                for (int i = 0; i < 5; i++) {
                    if (colorVector.at(i) == color) {
                        colorVector.erase(colorVector.begin() + i);
                    }
                }
            }
            return 0;
        }

3 个答案:

答案 0 :(得分:1)

您正在删除向量的元素,但是您希望访问所有五个元素(循环从0到5)。所以,让我们先删除第一个,然后尝试访问第4个元素。超出范围!

所以改变你的循环:

colorVector.erase(std::remove(colorVector.begin(),
                              colorVector.end(), color), colorVector.end());

更多关于erase-remove idiom

答案 1 :(得分:0)

当你调用vector::erase时,它将返回一个指向删除元素后面元素的新位置的迭代器。所以,如果我们删除这个元素:

1 2 3 4 5 6
      ^

我们的迭代器将自动更新为指向5.因此我们不必再次增加迭代器,它已经增加了一些。考虑到这一点:

auto it = colorVector.begin();
for (; it != colorVector.end(); /* do not increment it */ )
{
    if (*it == color) 
    {
        it = colorVector.erase(it); // erase and update
    }
    else
    {
        ++it; // just update
    }
}

当然,使用不易出错的算法会更好

colorVector.erase(
    std::remove(colorVector.begin(), colorVector.end(), color),
    colorVector.end()
);

答案 2 :(得分:-1)

您正在迭代期间修改 colorVector

一旦删除其中一种颜色,向量突然只有4个项目。现在,当你尝试转到第5项(在删除之前可以安全做) - 它崩溃了

试试这个:

for (int i = 0; i < colorVector.size(); i++) {
    if (colorVector.at(i) == color) {
        colorVector.erase(colorVector.begin() + i);
        --i;
    }
}

通过停在 colorVector.size 而不是硬编码 5 ,您可以确保列表永远不会超出范围。

编辑:
添加了--i语句以避免跳过下一个

Edit2:
正如下面的评论所述,从您当前正在迭代的阵列中删除项目通常是一个坏主意。