c ++在地图内返回对象的值

时间:2017-07-18 13:38:29

标签: c++

我的问题是我有一个非常基本的Node类:

struct Node {
    Node* next;
    Node* prev;
    int value;
    int key;
    Node(Node* p, Node* n, int k, int val) :prev(p), next(n), key(k), 
value(val) {};
    Node(int k, int val) :prev(NULL), next(NULL), key(k), value(val) {};
};

然后是一个存储Node对象地图的Cache类

class Cache {
protected:
    map<int, Node*> mp; //map the key to the node in the linked list
    int cp;  //capacity
    Node* tail; // double linked list tail pointer
    Node* head; // double linked list head pointer
    virtual void set(int, int) = 0; //set function
    virtual int get(int) = 0; //get function

};

最后,我有一个从Cache类派生的LRUCache类。

class LRUCache : public Cache {
public:
    LRUCache(int capacity) { cp = capacity; }
    virtual int get(int k) {
        std::map<int, Node*>::iterator it;
        it = mp.find(k);

        if (it != mp.end()) {
            return it->second->value;
        }
        else {
            return -1;
        }
    }

    virtual void set(int k, int v) {
        if (mp[k]) {
            mp[k] = new Node(k, v);
        }
        else {
            std::map<int, Node*>::iterator it = mp.begin();
            mp.insert(it, std::pair<int, Node*>(k, new Node(k, v)));
        }
    }
};

我遇到的错误是在这个LRUCache类的getter上。

返回此:“return it-&gt; second-&gt; value”给我这个错误:

LRUCache.exe:0xC0000005:读取路径0x00000008时发生内存访问冲突。

如果Node结构中的成员值“value”是公共的,为什么它会返回错误?

提前致谢

2 个答案:

答案 0 :(得分:1)

    if (mp[k]) {
        mp[k] = new Node(k, v);
    }
    else {
        std::map<int, Node*>::iterator it = mp.begin();
        mp.insert(it, std::pair<int, Node*>(k, new Node(k, v)));
    }

那里有两种可能性。如果k处的地图条目已经存在并且引用了非空Node,则Node被泄露并被另一个Node取代(这没有多大意义,但是在至少它不会立即导致崩溃)。

如果地图条目不存在,则mp[k]隐式创建一个,nullptr作为值(它也可能已经存在并且保存一个空指针;最终结果是一样的)。然后,您继续使用相同的密钥mp.insert()调用k - 这样做无效,因为该条目已存在。此处再次泄露Node - 但主要问题是地图中的空指针。

当您下次使用相同的键调用get()时,它会检索空指针并立即尝试取消引用它。这就是你的程序崩溃的地方。

答案 1 :(得分:0)

谢谢你,伊戈尔,正如你所说,问题出现在二传手中。

这个重构似乎有效:

    if (mp.find(k) != mp.end()) {
        auto it = mp[k];
        it->value = v;
    }
    else {
        auto it = mp.begin(); 
        mp.insert(it, std::pair<int, Node*>(k, new Node(k, v)));
    }