简单的 CPP 地图存储和访问无法按预期工作
simple cpp map store and access not working as expected
我有以下代码,它使用map根据键将节点插入mp。该类有两个函数集,分别用于插入和访问地图。
struct Node {
int value;
int key;
Node(int k, int val):key(k),value(val) {};
};
class Cache {
private:
map<int, Node*> mp;
Node* tail;
Node* head;
public:
void set(int, int);
void get(int);
};
void Cache::set(int key, int value) {
Node newN = Node(key, value);
mp.insert(std::pair<int, Node*>(key, &newN));
}
void Cache::get(int key) {
auto s = this->mp.find(key);
if (s != this->mp.end()) {
Node *nHit = s->second;
std::cout << "Map key = " << s->first;
std::cout << " : Node Key = " << nHit->key;
std::cout << ", value = " << nHit->value << "n";
}
}
下面是一个驱动程序主函数实现,它接受 2 行输入并输出键和值。
int main() {
int i;
Cache l;
for(i = 0; i < 2; i++) {
string command;
cin >> command;
if(command == "get") {
int key;
cin >> key;
l.get(key);
}
else if(command == "set") {
int key, value;
cin >> key >> value;
l.set(key, value);
}
}
return 0;
}
输入-
第2组 3
得到 2
输出-
映射键 = 2:节点键 = 32764,值 = -491659096
注意 - 输出键和值不断变化,并且每次运行都不固定。
为什么以及如何更改此处地图的键和值?
您正在插入指向函数范围值的指针。当函数 set() 退出时,值 newN 被销毁,并且映射中持有的指针无效。
要么你真的想要一个以 Node 实例作为值的映射;要么你需要在 set() 中使用 new 来分配你的对象,但你还需要记住删除它。您可以使用"智能"指针(如 shared_ptr 或 unique_ptr)来帮助管理此生命周期 - 尽管unique_ptr不会比使用实例带来任何优势。
在C++中,一段数据通常绑定到单个位置。 如果该位置是某个{ block scope; }
中的变量,则在结束}
处删除该变量。 例如,Cache::set
的右括号删除了newN
,并且对它的任何引用(包括mp
中的指针)不再指向任何地方。
C++还有第二个选择:某些数据的生存期可以由类控制。 例如,您输入的int
和Node*
值mp
与mp
一起被删除。 因此,您可以直接存储Node
而不是其地址,而不是将Node*
存储在 mp 中!
mp
的声明应该是
map<int, Node*> mp;
您可以插入
void Cache::set(int key, int value) {
mp.emplace(key, Node(key, value));
}
然后在main
你可以拥有
Node &nHit = s->second;
然后你可以用.
而不是->
来获得nHit
的成员。
你的另一种选择是使用智能指针,正如Jesper Juhl所提到的。 如果您仅将指针用于虚拟方法的多态性,请将std::unique_ptr<Node>
存储在mp
中,如果您希望在多个位置和mp
中使用某些Node
对象,则std::shared_ptr<Node>
很有用。
如果您只想引用已知生命周期的对象,并且希望将该引用存储在其他生命周期较短的对象中,则使用&
获取对象的地址(例如创建Node*
)非常有用。
除非在智能指针构造函数中,否则不要使用new Node(key, value)
,除非您准备自己单独delete
每个Node*
,并且永远不要犯错误。
您必须使用new
分配节点。 例如,
Node *newN = new Node(key, value);
mp.insert(std::pair<int, Node*>(key, newN));
因为它是你的节点在堆栈上,当函数返回时超出范围。
- OpenCV Tracker 属性访问在 ARM 上因 SEGFAULT 而失败,但在 X86_64 中工作
- 访问说明符(私有/公共/受保护)如何在内部工作(限制成员访问)?
- 访问其他线程堆栈变量如何在C++中工作?
- std::在地图上查找无法正常工作并循环访问地图的键和值
- 在为工作线程访问 lambda 中捕获的向量列表中的元素引用时,是否需要互斥锁?
- C PTHREAD_MUTEX在DB访问中无法正常工作
- 简单的 CPP 地图存储和访问无法按预期工作
- 为什么在发布模式下无法访问 for 循环,但在调试中它工作正常
- STD ::访问与STD ::变体的工作
- STD ::访问std ::变体无法正常工作
- c++libcurl无法访问,命令行正常工作
- 使查询在 MSADO 的访问中工作
- 在c++编译过程中,私有访问和公共访问是如何工作的
- 随机访问文件无法正常工作
- 插入[n X n]矩阵类型的数据,并在运行时对其进行访问.将std::映射工作
- 从静态方法访问非静态成员的工作示例
- 通过无序集访问类数据无法正常工作
- MFC:在工作线程中使用对象的成员函数时获取访问冲突错误
- 从工作线程访问对象
- 访问 nullptr 怎么可能工作