我使用map来存储键和指向链表中节点的指针。 创建映射后,我使用MyMap.find(key)来获取所需条目的迭代器。使用MyItr->秒我检索指向节点的指针。 但是当我访问存储在该节点的值时,该值设置为零。
MyMap定义为
map<int,Node*> MyMap; //map the key to the node in the linked list
结构如下:
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){};
};
功能集如下:
void set(int key,int value)
{
if(counter<cp)
{
if(counter==0)
{
Node node(0,0,key,value);
MyMap.insert(pair <int,Node*> (key,&node));
head=&node;
node.next=&node;
node.prev=&node;
prev_node=&node;
}
else
{
Node node(prev_node,head,key,value);
MyMap.insert(pair <int,Node*> (key,&node));
tail=&node;
//tail=&node;
}
counter++;
}
}
这是我的get(key)函数,用于返回值:
int get(int k)
{
//Node* node;
Myitrerator=MyMap.find(k);
if(Myitrator==MyMap.end())
{
return -1; // return -1 if not found
}
else
{
Node* np1=Myitrator->second;
return np1->value; // value to the corresponding key
// this always return 0 even if the address returned
//by Myiterator matches in debugger
}
}
这是主要功能:
int main() {
int n, capacity,i; // capacity of Cache
cin >> n >> capacity;
LRUCache l(capacity); // LRU is class contaning functions and map
for(i=0;i<n;i++) {
string command;
cin >> command;
if(command == "get") {
int key;
cin >> key;
cout << l.get(key) << endl;
}
else if(command == "set") {
int key, value;
cin >> key >> value;
l.set(key,value);
}
}
return 0;
}
Set(key,value)函数为链表创建新节点,并使用键将指针添加到地图中的该节点。
我知道双向链接列表没有正确实现,但是现在这并不是我所关心的,因为没有遍历列表来获取值。 我哪里错了?
答案 0 :(得分:0)
您的set()
函数存储指向Node
变量的指针,这些变量在堆栈的自动内存中实例化。当set()
退出时,变量超出范围,销毁Node
对象并将指针留在map
悬空中,因此当get()
尝试访问它们时它们无效。您的代码有未定义的行为。
您需要更改set()
以使用Node
运算符在堆上的动态内存中分配new
个对象。
void set(int key,int value)
{
if(counter<cp)
{
if(counter==0)
{
Node *node = new Node(0,0,key,value); // <--
MyMap.insert(std::make_pair(key,node));
head=node;
node->next=node;
node->prev=node;
prev_node=node;
}
else
{
Node *node = new Node(prev_node,head,key,value); // <--
MyMap.insert(std::make_pair(key,node));
tail=node;
}
counter++;
}
}
在某些时候,当你完成使用它们时,你将不得不迭代map
销毁Node
个对象:
for(std::map<int,Node*>::iterator iter = MyMap.begin(); iter != MyMap.end(); ++iter) {
delete iter->second;
}
如果您使用的是C ++ 11或更高版本,您可以考虑使用std:::unique_ptr
(或std::shared_ptr
与std::weak_ptr
,因为您正在创建链接列表)以让编译器处理当map
被销毁时,你会破坏节点:
std::map<int,std::unique_ptr<Node>> MyMap;
void set(int key,int value)
{
if(counter<cp)
{
if(counter==0)
{
std::unique_ptr<Node> node(new Node(0,0,key,value)); // <--
MyMap.insert(std::make_pair(key,std::move(node)));
head=node.get();
node->next=head;
node->prev=head;
prev_node=head;
}
else
{
std::unique_ptr<Node> node(new Node(prev_node,head,key,value)); // <--
MyMap.insert(std::make_pair(key,std::move(node)));
tail=node.get();
}
counter++;
}
}
int get(int k)
{
auto Myitrerator = MyMap.find(k);
if (Myitrator == MyMap.end())
return -1; // return -1 if not found
return Myitrator->second->value; // value to the corresponding key
}