运行时C++ "vector iterator not dereferencable"

C++ "vector iterator not dereferencable" in runtime

本文关键字:not dereferencable iterator vector C++ 运行时      更新时间:2023-10-16

实现这个简单的程序时,我发现,在运行时,当我在FIRST while的末尾键入eof时,发生了一个错误。错误提示"vector迭代器不可解引用"。这可能吗?迭代器在while循环之后声明!我还是不明白我拼错了什么。有人能帮帮我吗?程序应该检查一个向量是否是另一个向量的前缀。谢谢你!下面是主要函数:

   int main(){
        vector<int> v1, v2;
        cout << "1st vector: enter integers" << endl;
        int i, j;
        while (cin >> i){
            v1.push_back(i);
        }
        cout << "2nd vector: enter integers" << endl;
        while (cin >> j){
            v2.push_back(j);
        }
        vector<int>::const_iterator i1 = v1.begin();
        vector<int>::const_iterator i2 = v2.begin();
        while ((*i1) && (*i2) && ((*i1) == (*i2))){
            ++i1; ++i2;
        }
        if ((*i1) && (*i2))
            cout << "Vectors not compatible." << endl;
        else
        if (!(*i1))
            cout << "The 1st vector is a prefix for the 2nd." << endl;
        else
            cout << "The 2nd vector is a prefix for the 1st." << endl;
        return 0;
    }

vector<int>不是以空结尾的c样式字符串。因此,要检查迭代器是否到达终点,需要将它与终点迭代器进行比较。所以在这两种情况下都应该写成(i1 != v1.end()) && (i2 != v2.end())而不是(*i1) && (*i2)!(*i1)也一样。你应该把它改成i1 == v1.end()

@RSahu描述你遇到的第一个问题。一旦你解决了第一个问题,你就会遇到我描述的问题。

要解决他所描述的问题,您应该清除坏位并忽略cin缓冲区中剩下的任何内容。在第二个while循环之前添加以下行:

cin.clear();
cin.ignore();
生活

下面的代码块:

    while (cin >> i){
        v1.push_back(i);
    }

确保cin >> j失败。因此,块中的v2中没有添加任何内容:

    while (cin >> j){
        v2.push_back(j);
    }

由于v2为空,使用*i2会导致未定义的行为

一旦您获得cin上的第一个eof,它就停留在那里。第二个while循环实际上变成了一个noop,因为cin认为它已经完成了。从这里开始,我们运行:

vector<int>::const_iterator i1 = v1.begin();
vector<int>::const_iterator i2 = v2.begin();
while ((*i1) && (*i2) && ((*i1) == (*i2))){
                 ^^^
                 UB!

你在没有检查v2的大小的情况下解引用i2

首先,你必须清除std::cin:

std::cin.clear();

然后,检查是否完成vector操作的正确方法是将迭代器与end()进行比较(而不是简单地解引用):

while (i1 < v1.end() && i2 < v2.end() && *i1 == *i2) {
    ++i1;
    ++i2;
}

如果你有c++ 14编译器,你可以简单地使用std::mismatch:

auto res = std::mismatch(v1.begin(), v1.end(), v2.begin(), v2.end());
if (res.first < v1.end()) {
    if (res.second < v2.end()) {
        std::cout << "Not compatible!" << std::endl;
    }
    else {
        std::cout << "The 2nd vector is a prefix for the 1st." << std::endl;
    }
}
else {
    std::cout << "The 1st vector is a prefix for the 2nd." << std::endl;
}