我的问题是我有一个非常基本的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”是公共的,为什么它会返回错误?
提前致谢
答案 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)));
}