C++ :cannot seek vector iterator before begin

标签 c++ vector iterator

我正在做一个uva问题uva 10935 throwing cards away ,我的代码如下。当我运行它时,它说引发了未处理的异常:读取访问冲突,并且还显示“无法在开始之前寻找 vector 迭代器”,我不知道我的代码中的问题出在哪里:

#include<vector>
#include<iostream>
using namespace std;
int n;
vector<int> out;


int main() {
    freopen("data.txt", "r", stdin);
    while (scanf("%d", &n) == 1 && n) {
        vector<int> cards;
        for (int i = 1; i <= n; i++)cards.push_back(i);
        vector<int>::iterator it = cards.begin();
        vector<int>::iterator end = cards.end();
        while (it != (end-1)) {
            out.push_back(*it);
            it++;
            cards.push_back(*it);
            it++;
            end++;
        }
        cout << "Discarded cards: ";
        for (int j = 0; j < out.size(); j++) {
            if(j!=(out.size()-1))cout << out[j] << ", ";
            else cout << out[j] << endl;

        }
        cout << "Remaining card: " << *it << endl;
    }
    return 0;
}

最佳答案

这里的问题仍然存在于 while() 循环中,您在 vector 中推送新元素,同时保留旧的“结束”地址作为终端引用

当 vector 推送新元素时,它可能需要将整个数组重新分配到新位置。在这种情况下,当您线性增加它时,您所持有的“end引用将变得过时,但是插入之后的整个 vector 可能已经转移到其他地方了。

我在您的代码中添加了一些调试行,以便您可以看到这是如何发生的。 只需运行输入值为 4 的代码。你会看到“结束”值可能不再与 vector 的重新分配地址相关(如果发生重新分配,它基本上取决于系统来决定)。

#include<vector>
#include<iostream>
using namespace std;
int n;
vector<int> out;

void printVectorElementAddresses(vector<int> &v){
    cout<<"==== Vector Element Addresses ====\n";
    for(auto itr = v.begin(); itr != v.end(); itr++)
    {
        cout<<&(*itr);
        if(itr == v.end()-1){
            cout<<endl;
        }
        else{
            cout<<" ";
        }
    }
    cout<<endl;
}

void printIteratorAddressWithTag(char* tag, vector<int> :: iterator & it, bool printNewLine){
    cout<<tag<<&*it<<"; ";
    if(printNewLine){
        cout<<endl;
    }
}

int main() {
//    freopen("data.txt", "r", stdin);
    while (scanf("%d", &n) == 1 && n) {
        vector<int> cards;
        for (int i = 1; i <= n; i++)cards.push_back(i);
        vector<int>::iterator it = cards.begin();
        vector<int>::iterator end = cards.end();

        //print vector addresses after initial pushes are done
        printVectorElementAddresses(cards);

        while (it != (end-1)) {
            printIteratorAddressWithTag("it initial = ", it, false);
            out.push_back(*it);
            it++;

            printIteratorAddressWithTag("it after first increment = ", it, false);
            cards.push_back(*it);
            it++;

            printIteratorAddressWithTag("it after second increment = ", it, true);

            printIteratorAddressWithTag("end initially in loop = ", end, false);
            end++;

            printIteratorAddressWithTag("end after increment = ", end, true);

            cout<<"Vector Addresses after a new push"<<endl;
            printVectorElementAddresses(cards);
        }
        cout << "Discarded cards: ";
        for (int j = 0; j < out.size(); j++) {
            if(j!=(out.size()-1))cout << out[j] << ", ";
            else cout << out[j] << endl;

        }
        cout << "Remaining card: " << *it << endl;
    }
    return 0;
}

只需更改 while 循环中的逻辑即可在推送发生后跟踪旧的“结束”引用。如果其他逻辑没问题,它应该可以工作。

关于C++ :cannot seek vector iterator before begin,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60123957/

相关文章:

c++ - 加快一些 SSE2 Intrinsics 的颜色转换

c++ - 具有对齐存储的动态内存分配

c++ - 结构中的 vector - 最佳方法? C++

c++ - Point2f vector 的最小值和最大值

php - 是否可以倒回 PDO 结果?

C++ 指针作用域

c++ - 指针除了存地址,怎么实现呢?

C++:检查 vector 中所有对象属性的值

c++ - 在字符串中使用删除函数是否会使迭代器无效

c++ - 如何让编译器推断出我的模板迭代器的类型?