简体   繁体   English

C ++在运行时“向量迭代器不可引用”

[英]C++ “vector iterator not dereferencable” in runtime

implementing this simple program I found out, in runtime, an error that occurs when i type the eof at the end of the FIRST while. 在执行此简单程序时,我在运行时发现了在FIRST while末尾键入eof时发生的错误。 The error says " vector iterator not dereferencable ". 错误显示“ 向量迭代器不可解除 ”。 Is that possible? 那可能吗? The iterators are declared after the while cycles! 迭代器在while循环之后声明! I still cannot understand what i misspelled. 我仍然不明白我拼错了什么。 Can someone help me? 有人能帮我吗? Ps. 附言 The program should check if a vector is a prefix for the other. 程序应检查向量是否是另一个的前缀。 Thank you! 谢谢! Here's the main function: 主要功能如下:

   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> is not a null-terminated c-style string. vector<int>不是以N结尾的c样式字符串。 So to check whether an iterator reached the end, you need to compare it with the end iterator. 因此,要检查迭代器是否到达末尾,需要将其与末尾迭代器进行比较。 So instead of (*i1) && (*i2) you should write (i1 != v1.end()) && (i2 != v2.end()) in both cases. 因此,在两种情况下都应该写(i1 != v1.end()) && (i2 != v2.end())而不是(*i1) && (*i2) Same goes for !(*i1) . !(*i1) You should change it to i1 == v1.end() . 您应该将其更改为i1 == v1.end()

@RSahu describes the first problem you hit. @RSahu描述了您遇到的第一个问题。 You will hit the problem that I described once you fix the first one. 修复第一个问题后,您将遇到我描述的问题。

To fix the problem he described, you should clear the bad bits and ignore whatever is left in cin 's buffer. 要解决他描述的问题,您应该清除不良位,并忽略cin缓冲区中剩余的内容。 Add the following lines before your second while loop: 在您的第二个while循环之前添加以下行:

cin.clear();
cin.ignore();

LIVE 生活

Once you get the first eof on cin , it stays there. 一旦您在cin上获得了第一个eof,它就会保留在那里。 The second while loop effectively becomes a noop, since cin thinks it's done. 由于cin认为已完成,因此第二个while循环实际上变成了无事。 From there, we run through: 从那里开始,我们进行以下操作:

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

And you're dereferencing i2 without checking v2 's size. 并且您在不检查v2大小的情况下取消引用i2

First, you have to clear std::cin : 首先,您必须清除std::cin

std::cin.clear();

And then, the right way to check if you're done with a vector is to compare the iterator to end() (as opposed to simply dereferencing): 然后,检查向量是否正确的正确方法是将迭代器与end()进行比较(与简单地取消引用相反):

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

Though if you have access to a C++14 compiler, you could simply use std::mismatch : 虽然如果可以访问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;
}

The following block: 以下块:

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

makes sure that cin >> j fails. 确保cin >> j失败。 Hence, nothing gets added to v2 in the block: 因此,该块中没有任何内容添加到v2

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

Since v2 is empty, using *i2 leads to undefined behavior. 由于v2为空,因此使用*i2会导致未定义的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM