C++用list容器的反向迭代器为什么会崩溃,环境是VS2019

发布于 2022-09-11 22:22:48 字数 2951 浏览 36 评论 0

首先定义了一个list,然后往list中加入了一个元素,用一个正向迭代器指向这个元素,关键的地方来了,
这时我用这个正向迭代器初始化了一个反向迭代器,在操作这个反向迭代器的时候发生了异常。请问这个反向迭代器到底指向哪里呢?

clipboard.png

源代码如下,在main函数中第二次执行cache.put(1, 1)的时候就会引发异常,我尝试对rit进行了++或--的操作,但始终无法指向初始化它的正向迭代器it的位置,it指向的数据是1,1,1,可以参考图上的局部变量信息。

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <string>
#include <stack>
#include <map>
#include <list>
using namespace std;


struct Data {
    int count;
    int key;
    int value;
    Data(int count, int key, int value) : count(count), key(key), value(value) {}
};
class LFUCache {
private:
    map<int, list<Data>::iterator> m;
    list<Data> l;
    int c;
public:
    LFUCache(int capacity) {
        c = capacity;
    }

    void print() {
        cout << "cur link list:";
        for (auto it = l.rbegin(); it != l.rend(); it++) {
            cout << it->key << " ";
        }
        cout << endl;
    }

    int get(int key) {
        if (m.find(key) != m.end()) {
            list<Data>::iterator it = m[key];
            Data data = *it;
            list<Data>::reverse_iterator rit(it);
            list<Data>::iterator pos = l.end();
            while (rit->count >= data.count && rit != l.rend()) {
                rit++;
            }
            pos = rit.base();
            m[key] = l.insert(pos, data);
            l.erase(it);
            return m[key]->value;
        }
        return -1;
    }

    void put(int key, int value) {
        if (c == 0) {
            return;
        }
        list<Data>::iterator it;
        if (m.find(key) == m.end()) {
            if (l.size() < c) {
                l.push_back(Data(1, key, value));
            }
            else {
                m.erase(l.back().key);
                l.pop_back();
                l.push_back(Data(1, key, value));
            }
            it = l.end();
            it--;
        }
        else {
            it = m[key];
            m[key]->count++;
        }
        Data data = *it;
        list<Data>::reverse_iterator rit(it);
        list<Data>::iterator pos = rit.base();
        rit++;
        while (rit->count >= data.count && rit != l.rend()) {
            rit++;
        }
        pos = rit.base();
        if (pos != l.end()) {
            m[key] = l.insert(pos, data);
            l.erase(it);
        }
        else {
            m[key] = it;
        }
    }
};
int main() {
    LFUCache cache = LFUCache(2);
    cache.put(1, 1);
    cache.put(1, 1);
    cache.put(2, 2);
    cache.put(3, 3);
    cache.put(2, 2);
    cache.put(3, 3);
    cout << cache.get(1) << endl;
    cout << cache.get(2) << endl;
    cout << cache.get(3) << endl;
}
    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

九八野马 2022-09-18 22:22:48

list<Data>::reverse_iterator rit(it);

此时,rit 指向的是 it (也就是 rit.base()) 的前一个元素。

第二次插入,list 中只有一个元素,it 实际就是 begin() ,rit 实际是 rend() 。此时 rit 已经不能 ++ 了。

===============

end 是最后一个元素后的一个元素, rend 是第一个元素之前的一个元素,这两个都不能解引用,也都不能 ++ 。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文