指向结构的指针保留某些属性,同时将其他属性重置为零(使用 map)

Pointer to a structure retains certain properties while resetting others to zero (using map)

本文关键字:属性 其他 map 使用 指针 结构 保留      更新时间:2023-10-16

我正在使用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(键,值(函数向链表创建新节点,并使用键将指向映射中该节点的指针添加。

我知道双向链表没有正确实现,但到目前为止,这不是我关心的问题,因为没有遍历列表以获取值。我哪里做错了?

您的set()函数存储指向在堆栈上的自动内存中实例化的Node变量的指针。 当set()退出时,变量会超出范围,从而破坏Node对象并使map中的指针悬而未决,因此当get()尝试访问它们时,它们无效。 您的代码具有未定义的行为

您需要更改set()以使用 new 运算符在堆上的动态内存中分配Node对象。

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++;
    }
}

在某些时候,当您使用完Node对象时,您必须迭代销毁map

for(std::map<int,Node*>::iterator iter = MyMap.begin(); iter != MyMap.end(); ++iter) {
    delete iter->second;
}

如果您使用的是 C++11 或更高版本,则可以考虑使用 std:::unique_ptr(或与 std::weak_ptr 一起使用std::shared_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 
}
相关文章: